2012年7月26日 星期四

(Android Note) 了解螢幕解析度機制

1. Introduction


        目前手機或平板電腦市場,有各種不同節析度存在,為了要讓美工製圖能呈現最優質的畫質,必須要了解圖片擺放位置和解析度格式。


2. Article


2.1 圖型資料夾


        圖形資源分配可分成5種資料夾格式,drawable、drawable-xhdpi、drawable-hdpi、drawable-mhdpi、drawable-ldpi,每種資料夾所支援節析度格式也會不同,稍後2.3說明。手機會依照螢幕節析度的需求,會自動尋找到適合的圖片。




2.2   AndroidManifest.xml 設定


需要在 AndroidManifest.xml 內加入以下語法,手機才會自動抓到符合本身螢幕節析度資源。


<supports-screens
          android:largeScreens="true"
          android:normalScreens="true"
          android:smallScreens="true"
          android:anyDensity="true" />


2.3 節析度格式


       由圖中紅框可以看到,ldpi (密度值 120) 最佳支援 WQVGA400 (240X400) WQVGA432 (240X432)、mdpi (密度值 160) 最佳支援 HVGA (320X480)、hdpi (密度值 240) 最佳支援 WVGA800 (480X800) WVGA854 (480X854)  600X1024、xhdpi (密度值 320) 最佳支援 640X960。



     在這邊簡單說明密度值的作用,如果要在不同的手機或平板電腦看到一樣節析度的畫質,就必須依照資料夾的密度作調整。
EX:
mdpi 放置一張 100X100的照片
1. 
有支手機支援 drawable-ldpi格式,所需要 ldpi 密度為120是mdpi的0.75倍,圖片在手機上會自動調整最佳節析度大小,呈現75X75。
2.
有支手機支援 drawable-hdpi格式,所需要 hdpi 密度為240是mdpi的1.5倍,圖片在手機上會自動調整最佳節析度大小,呈現150X150小部分失真。
3.
有支手機支援 drawable-xhdpi格式,所需要 xhdpi 密度為320是mdpi的2倍,圖片在手機上會自動調整最佳節析度大小,呈現200X200大部分失真。
4.
把drawable-*等資料夾都刪除,只留下drawable資料夾,在手機上的圖形會依照原本繪製大小1:1的呈現。


3. 手機和平板規格


3.1 Density 120


遠傳小精靈(320x240)
HTC野火機1代(320x240)


3.2 Density 160

HTC Hero(480x320)
HTC Flyer平板(1024x600)

3.3 Density 170


Samsung Tab 7.7(1024x600)

3.4 Density 240

Nexus one(800x480)
Nexus S(800x480)
HTC Desire(800x480)
HTC Incredible(800x480)
Sony Arc(854x480)
Samsung SII(800x480)

3.5 Density 320

Galaxy Nexus(1280x720)

3.6 規格

QVGA = 320 * 240;
WQVGA = 320 * 480;
WQVGA2 = 400 * 240;
WQVGA3 = 432 * 240;
HVGA = 480 * 320;
VGA = 640 * 480;
WVGA = 800 * 480;
WVGA2 = 768 * 480;
FWVGA = 854 * 480;
DVGA = 960 * 640;
PAL = 576 * 520;
NTSC = 486 * 440;
SVGA = 800 * 600;
WSVGA = 1024 * 576;
XGA = 1024 * 768;
XGAPLUS = 1152 * 864;
HD720 = 1280 * 720;
WXGA = 1280 * 768;
WXGA2 = 1280 * 800;
WXGA3 = 1280 * 854;
SXGA = 1280 * 1024;
WXGA4 = 1366 * 768;
SXGAMINUS = 1280 * 960;
SXGAPLUS = 1400 * 1050;
WXGAPLUS = 1440 * 900;
HD900 = 1600 * 900;
WSXGA = 1600 * 1024;
WSXGAPLUS = 1680 * 1050;
UXGA = 1600 * 1200;
HD1080 = 1920 * 1080;
QWXGA = 2048 * 1152;
WUXGA = 1920 * 1200;
TXGA = 1920 * 1400;
QXGA = 2048 * 1536;
WQHD = 2560 * 1440;
WQXGA = 2560 * 1600;
QSXGA = 2560 * 2048;
QSXGAPLUS = 2800 * 2100;
WQSXGA = 3200 * 2048;
QUXGA = 3200 * 2400;
QFHD = 3840 * 2160;
WQUXGA = 3840 * 2400;
HD4K = 4096 * 2304;
HXGA = 4096 * 3072;
WHXGA = 5120 * 3200;
HSXGA = 5120 * 4096;
WHSXGA = 6400 * 4096;
HUXGA = 6400 * 4800;
SHV = 7680 * 4320;
WHUXGA = 7680 * 4800;



2012年7月25日 星期三

(Android Note) 拖曳圖片

1. 說明: 拖曳icon, 並且記錄 icon目前位置

2. Drag_Drop.java

package com.kochi.knowhow;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Drag_Drop extends Activity {
    /** Called when the activity is first created. */
private ImageView img;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drag_drop);
        img = (ImageView)findViewById(R.id.dragdropImageView1);
        img.setOnTouchListener(imgListener);
    }
 
    private OnTouchListener imgListener = new OnTouchListener(){
    private float x, y; //原本圖片存在的X,Y軸位置
    private int mx, my; //圖片被拖曳的X ,Y軸距離長度
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
//Log.e("View", v.toString());
switch(event.getAction()) {  
//按下圖片時
case MotionEvent.ACTION_DOWN:  
                x = event.getX();  
                y = event.getY();
            //移動圖片時
            case MotionEvent.ACTION_MOVE:  
                mx = (int)(event.getRawX() - x);  
                my = (int)(event.getRawY() - 50 - y); //50應該是標題框長度
                v.layout(mx, my, mx + v.getWidth(), my + v.getHeight());  
                break;  
            }
Log.e("address", String.valueOf(mx)+"~~"+String.valueOf(my)); //記錄目前位置
            return true;  
}
    };
}

3. drag_drop.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
 <ImageView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:src="@drawable/icon"
    android:id="@+id/dragdropImageView1"></ImageView>

</LinearLayout>






(Android Note) 設定,取得偏好設定SharedPreferences

1. 說明: 利用SharedPreferences類別, 設定和取得偏好設定內容(姓名,生日,電話)

2. SetGetSharedPreferences.java


package com.kochi.knowhow;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class SetGetSharedPreferences extends Activity{
private EditText name;
private EditText birthday;
private EditText tel;
private Button set;
private Button get;
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sharedpreferences);
        name = (EditText) findViewById(R.id.spName);
        birthday = (EditText) findViewById(R.id.spBirthday);
        tel = (EditText) findViewById(R.id.spTel);
        set = (Button) findViewById(R.id.spSet);
        get = (Button) findViewById(R.id.spGet);
       
        set.setOnClickListener(setListener); //設定監聽模式
        get.setOnClickListener(getListener); //取得監聽模式
}
//按下設定按鈕
private OnClickListener setListener = new OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

//getSharedPreferences(String name,int mode) , name為設定檔名稱
//MODE_PRIVATE : 只有此程式可以存取
//MODE_WORLD_READABLE : 其它程式也可以讀取
        //MODE_WORLD_WRITEABLE : 其它程式可以寫
//MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE : 其它程式可讀取寫入
SharedPreferences setting = getSharedPreferences("SP", MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE);
//把name,birthday,tel變數儲存Name,Birthday,Tel屬性, 必須要加入.commit()才會建立此檔案
setting.edit().putString("Name",name.getText().toString()).commit();
setting.edit().putString("Birthday",birthday.getText().toString()).commit();
setting.edit().putString("Tel",tel.getText().toString()).commit();

//清空EditText內容
name.setText("");
birthday.setText("");
tel.setText("");
}

};
//按下取得按鈕
private OnClickListener getListener = new OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

//getSharedPreferences(String name,int mode) , name為設定檔名稱
SharedPreferences getting = getSharedPreferences("SP", 0);
//讀取Name屬性值,再顯示EditText框架上
name.setText(getting.getString("Name", ""));
//讀取Birthday屬性值,再顯示EditText框架上
birthday.setText(getting.getString("Birthday", ""));
//讀取Tel屬性值,再顯示EditText框架上
tel.setText(getting.getString("Tel", ""));
}

};
}

3. sharedpreferences.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView android:text="姓名" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <EditText android:layout_height="wrap_content" android:text="" 
    android:id="@+id/spName" android:layout_width="match_parent" android:inputType="text"></EditText>
    <TextView android:text="生日" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <EditText android:layout_height="wrap_content" android:text="" 
    android:id="@+id/spBirthday" android:layout_width="match_parent" android:inputType="date"></EditText>
    <TextView android:text="電話" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <EditText android:layout_height="wrap_content" android:text="" 
    android:id="@+id/spTel" android:layout_width="match_parent" android:inputType="number"></EditText>
   
    <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button android:text="設定" android:id="@+id/spSet" 
      android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    <Button android:text="取得" android:id="@+id/spGet" 
      android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
    </LinearLayout>
   
</LinearLayout>

4. 執行步驟
a. 輸入內容,按下設定按鈕

b. 按下設定按鈕後,清空EditText 

c. 按下取得按鈕, 會讀取在偏好設定的值

5. 偏好設定會存在
(/data/data/com.kochi.knowhow/shared-prefs/SP.xml)
以下權限為 MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE : 其它程式可讀取