2010年10月20日 星期三

Android Resources 資源檔-使用(三)

resourceID的值由兩個部份組成type(如string)與name(如hello)
取得Resource的方式
一.在Java Code中使用resource
1.取得resourceID的語法為
package_name.R.resource_type.resource_name
若在自己專案內package_name可以不用寫

R.string.hello
android.R.color.secondary_text_dark
2.取得Resource Class
利用 Context.getResources()取得Resource Class
再利用Resource提供的各項method來取得各類型的resource
3.範例
例1:
Resources res=Context.getResources();
String str=res.getString(R.string.hello)
例2:
TextView.setText(rsid:int)就可直接使用,用自己找出resources
例3:
imageView.setImageResource(R.drawable.myimage);
二.在XML中使用resource
1.取得resourceID的語法為
@package_name:resource_type/resource_name
如果是在自己專案內的resource就不用寫package_name
在tag內將resourceID指定給tag,tag即會利用resourceID取得資源
2.使用sttle的語法為
?package_name:resource_type/resource_name

2.範例
例1:
 <?xml version="1.0" encoding="utf-8"?>  
 <EditText xmlns:android="http://schemas.android.com/apk/res/android"  
      android:layout_width="fill_parent"  
      android:layout_height="fill_parent"  
      android:textColor="@android:color/secondary_text_dark"  
      android:text="@string/hello" />       
以上範例,textColor用到android內建的資源,所以用@android:color/secondary_text_dark
而text用到是自己專案內的資源,所以用@string/hello
例2:
 <EditText id="text"  
           android:layout_width="fill_parent"  
           android:layout_height="wrap_content"  
           android:textColor="?android:textColorSecondary"  
           android:text="@string/hello_world" />       

三.使用系統內建resource
若要使用系統預設的resource,可用android.R取得
注意:R是本身專案的resource檔案,而android.R是系統提供的預設resource檔


四.執行過程中的異動
當使用者的Device在使用過程中做了變動,譬如說,旋轉或改變語系,系統會因為這樣的改變而將正在進行的Activity進行onDestroy(),然後進行onCreate()重新顯示以套用新的改變。
而在進行onDestroy()前會進行資料儲存動作,好讓重新建立後可以回復資料,其流程如下
onSaveInstanceState()->onDestroy()->onCreate()->onRestoreInstanceState()
其執行方式有以下兩種方式,各有優缺點
1.保留資訊,自動重新啟動
當config改變發生時,允許Activity在自動restart,並把狀態資料帶到Activity新的instance上,若要重新建立新的instance,如果資料來源是來自網路,可能會因為重新建立連線而發生更久的時間。
通常用來儲存狀態用的都是bundle物件,但bundle物件並不適合儲存大量資料(如點陣圖),所以在runtime時要保留資料會是用以下作法
1.Override onRetainNonConfigurationInstance()回傳你要儲存
  的物件,onRetainNonConfigurationInstance()會發生在
  onStop()與onDestroy()之間
2.當create後呼叫getLastNonConfigurationInstance()取回物件

儲存
@Override
public Object onRetainNonConfigurationInstance() {
    final MyDataObject data = collectMyLoadedData();
    return data;
}    
取回
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
    if (data == null) {
        data = loadMyData();
    }
    ...
}    
2.取得通知,自己手動處理改變的訊息
當config改變發生時,只發出相關通知,讓使用者自己決定是否要restart,為了效能考量,在部份config發生改變時,並不自動restart Activity,就需要使用者自己手動去處理外觀異動的部份,而無法享受到使用衍生res所帶來的方便
作法如下:
1.先在Manifest內設定Activity要監聽哪些事件變化
2.覆寫onConfigurationChanged(),當有config改變時,
  這裡會接收到新的config物件

manifest.xml
 <activity android:name=".MyActivity"  
       android:configChanges="orientation|keyboardHidden"  
       android:label="@string/app_name">  

Activity內
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
    // Checks whether a hardware keyboard is available
    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
    }
}    

沒有留言: