標籤:android style blog http color 使用 io strong
在android中,可以很容易給一個視圖的外觀加上state,從而反映行為狀態比如:啟用、選中、懸浮等。但是對於視圖布局的動態調整,比如說某一狀態,需要顯示按鈕,下一個狀態,不需要顯示這個按鈕,就顯得蒼白無力。
這種情況,大家會說我去改一下按鈕的可見度就ok了呀。的確是這樣,但是涉及到多個狀態、多個控制項的時候是不是很麻煩?現有解決辦法主要問題有:
(1) 多狀態、多組件的難於管理。
(2) 沒用的組件只是看不見了,但是還存在,浪費資源。
有沒有更好的方法?有,那就是引入state。
先看:
這個是預設狀態的:
點擊show clicked按鈕,變成:
最後,點擊show all,切換到all狀態:
這裡面有兩個組件: 按鈕和文字框,三種狀態:default、clicked、all。default下顯示文字框,clicked下顯示按鈕,all下顯示所有。
怎麼做的?
首先需要定義狀態
在狀態視圖的layout上用tractor:states定義所有狀態,tractor:currentState指定預設狀態。如下面代碼所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tractor="http://schemas.tractorframework.com/tractor" ... tractor:states="default,clicked,all" tractor:currentState="default" tractor:layout="activity_main" >
還有一個標籤是trantor:layout,這個是用來指定狀態視圖的layout的,在狀態切換的時候,需要這個參數來獲得layout,重新構造整個視圖。也就是說狀態視圖的layout都需要
一個單獨的layout檔案來定義。有點小不方便,但是對於大量的可見度管理來說,可以接受,您說呢?
在控制項上聲明對應狀態
在視圖控制項上使用tractor:includeIn來表明該控制項存在於哪些狀態下,或者用tractor:excludeFrom來指定不存在於哪些狀態。下面是例子程式的兩個控制項的狀態聲明:
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" tractor:includeIn="clicked,all" android:text="hello clicked state" /> <EditText android:id="@+id/editText" android:layout_width="wrap_content" android:layout_height="wrap_content" tractor:excludeFrom="clicked" android:text="hello default state" />
按鈕存在於clicked,all兩個狀態,文字框不存在於clicked狀態,也就是說存在於default和all狀態。
狀態切換
上面都是定義和聲明,是不是很簡單?狀態切換也不複雜,在上面例子上,最上面的三個按鈕就是切換狀態用的,它們被點擊後,就會去切換對應狀態。比如show clicked按鈕點擊就會去切換到clicked狀態,代碼是這樣的:
public void switchToClicked(View v) { View root = findViewById(R.id.root); sf.getViewState(root).setCurrentState("clicked"); }
首先得到狀態視圖,其次得到狀態試圖對應的ViewState去設定目前狀態。一切很容易操作的了,但是大家會說sf是什麼,看下面。
最核心的是加入狀態支援,在Activity設定視圖之前,重新設定LayoutInflater的Factory2工廠,這個在sdk版本11才有哦。這個sf就是加入了狀態支援的Factory2工廠執行個體。
例子程式的Activity是這樣構造的:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); createInflator(); setContentView(R.layout.activity_main); } private void createInflator() { LayoutInflater inflater = LayoutInflater.from(this); sf = new StateFactory(inflater); inflater.setFactory2(sf); }
核心代碼就是StateFactory。這個地方可以下載整個例子程式,裡面有StateFactory的代碼。整個例子只是示範用的,StateFactory實現的也有不妥的地方,但是我們可以看到android支援檢視狀態的可能性。有了state,android 視圖代碼又會好寫很多,一切目標:簡單。您說呢 ?