drawable 下 selector 狀態

我們在使用drawable 的時候,會使用各種狀態,如下面描述:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize=["true" | "false"]
    android:dither=["true" | "false"]
    android:variablePadding=["true" | "false"] >
    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_hovered=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_activated=["true" | "false"]
        android:state_window_focused=["true" | "false"] />
</selector>

我們該如何選擇用哪一個呢?

官方文檔:https://developer.android.com/guide/topics/resources/drawable-resource#StateList  (顏色及狀態列表)

android:state_pressed

布爾值。如果在按下對象(例如觸摸/點按某按鈕)時應使用此項目,則值爲“true”;如果在默認的未按下狀態時應使用此項目,則值爲“false”。

android:state_focused

布爾值。如果在對象具有輸入焦點(例如當用戶選擇文本輸入時)時應使用此項目,則值爲“true”;如果在默認的非焦點狀態時應使用此項目,則值爲“false”。

android:state_hovered

布爾值。如果當光標懸停在對象上時應使用此項目,則值爲“true”;如果在默認的非懸停狀態時應使用此項目,則值爲“false”。通常,這個可繪製對象可能與用於“聚焦”狀態的可繪製對象相同。

此項爲 API 級別 14 新引入的配置。

android:state_selected

布爾值。如果在使用定向控件瀏覽(例如使用方向鍵瀏覽列表)的情況下對象爲當前用戶選擇時應使用此項目,則值爲“true”;如果在未選擇對象時應使用此項目,則值爲“false”。

當焦點 (android:state_focused) 不充分(例如,列表視圖有焦點但使用方向鍵選擇其中的項目)時,使用所選狀態。

android:state_checkable

布爾值。如果當對象可選中時應使用此項目,則值爲“true”;如果當對象不可選中時應使用此項目,則值爲“false”。(僅當對象可在可選中與不可選中小部件之間轉換時纔有用。)

android:state_checked

布爾值。如果在對象已選中時應使用此項目,則值爲“true”;如果在對象未選中時應使用此項目,則值爲“false”。

android:state_enabled

布爾值。如果在對象啓用(能夠接收觸摸/點擊事件)時應使用此項目,則值爲“true”;如果在對象停用時應使用此項目,則值爲“false”。

android:state_activated

布爾值。如果在對象激活作爲持續選擇(例如,在持續導航視圖中“突出顯示”之前選中的列表項)時應使用此項目,則值爲“true”;如果在對象未激活時應使用此項目,則值爲“false”。

此項爲 API 級別 11 新引入的配置。

android:state_window_focused

布爾值。如果當應用窗口有焦點(應用在前臺)時應使用此項目,則值爲“true”;如果當應用窗口沒有焦點(例如,通知欄下拉或對話框出現)時應使用此項目,則值爲“false”。

:請記住,Android 將應用狀態列表中第一個與對象當前狀態匹配的項目。因此,如果列表中的第一個項目不含上述任何狀態屬性,則每次都會應用它,這就是默認值應始終放在最後的原因(如以下示例所示)。 

這個就是我們有時候selector 不起作用的原因,不過爲了避免這種情況,我們不去偷懶,把每種情況都描述,不用缺省默認狀態,這樣就不會出現問題來。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@drawable/button_pressed" /> <!-- pressed -->
    <item android:state_focused="true"
          android:drawable="@drawable/button_focused" /> <!-- focused -->
    <item android:state_hovered="true"
          android:drawable="@drawable/button_focused" /> <!-- hovered -->
    <item android:drawable="@drawable/button_normal" /> <!-- default -->
</selector>

————————————————————————————————————————————————————————

以上,爲官方講解:下面說說自己的理解;

我們常用的也就幾個,每個狀態的前提,影響條件纔是我要關心的,所以,寫一個demo 來去驗證一下:

 Log.d("tag", "hasFocus"  + tv1.hasFocus())
        Log.d("tag", "isFocused"  + tv1.isFocused)
        Log.d("tag", "hasFocusable"  + tv1.hasFocusable())
        Log.d("tag", "isPressed"  +  tv1.isPressed)
        Log.d("tag", "isEnabled"  +  tv1.isEnabled)
        Log.d("tag", "isSelected"  +  tv1.isSelected)
        
        tv1.setClickable(false)

        Log.d("tag", "click false hasFocus"  + tv1.hasFocus())
        Log.d("tag", "click false isFocused"  + tv1.isFocused)
        Log.d("tag", "click false hasFocusable"  + tv1.hasFocusable())
        Log.d("tag", "click false isPressed"  +  tv1.isPressed)
        Log.d("tag", "click false isEnabled"  +  tv1.isEnabled)
        Log.d("tag", "click false isSelected"  +  tv1.isSelected)
        tv1.setOnClickListener {
            Log.d("tag", "tv1 被點擊了")

            Log.d("tag", "click hasFocus"  + tv1.hasFocus())
            Log.d("tag", "click isFocused"  + tv1.isFocused)
            Log.d("tag", "click hasFocusable"  + tv1.hasFocusable())
            Log.d("tag", "click isPressed"  +  tv1.isPressed)
            Log.d("tag", "click isEnabled"  +  tv1.isEnabled)
            Log.d("tag", "click isSelected"  +  tv1.isSelected)


        }

 打印結果:

D/tag: hasFocusfalse
D/tag: isFocusedfalse
D/tag: hasFocusablefalse
D/tag: isPressedfalse
D/tag: isEnabledtrue
D/tag: isSelectedfalse
D/tag: click false hasFocusfalse
D/tag: click false isFocusedfalse
D/tag: click false hasFocusablefalse
D/tag: click false isPressedfalse
D/tag: click false isEnabledtrue
D/tag: click false isSelectedfalse

點擊事件後:

D/tag: tv1 被點擊了
D/tag: click hasFocusfalse
D/tag: click isFocusedfalse
D/tag: click hasFocusabletrue
D/tag: click isPressedtrue
D/tag: click isEnabledtrue
D/tag: click isSelectedfalse

這裏有一個點就是在設置了 clickable (false) ,好沒有作用 ,原因是我們點開 setOnclickListener () 看源碼就知道了。

public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

這裏會自動在次設置爲可以點擊點狀態。

 

所以給一個小結論吧。

// checked 只能對checkbox 和 radioButton 觸發
// select 狀態也是要設置 setSelected()
// pressed 可以通過點擊事件觸發 ;在按下對象(例如觸摸/點按某按鈕)時應使用此項目 isPressed 來獲取按壓狀態
// focus 可以進行代碼設置 requestFocus ;或者對於editText 可以通過手勢獲取焦點
// state_hovered 光標停留對地方,不常用。
// state——enable 如果在對象啓用(能夠接收觸摸/點擊事件)時應使用此項目; 通過setEnable 設置
// state_window_focused 如果當應用窗口有焦點(應用在前臺)時應使用此項目,則值爲“true”;如果當應用窗口沒有焦點(例如,通知欄下拉或對話框出現)時應使用此項目,則值爲“false”。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章