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”。

 

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