Android 设置获取焦点、失去焦点的按压状态

194 阅读1分钟

背景

一般来说UI一般设计成View 获取焦点时候给其背景增加边框。现在遇到了一个比较有意思的问题。有焦点的跟没有焦点的按压背景不一样的。

有焦点的按压背景

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <stroke android:width="2dp" android:color="@color/color_fff2a900" />
    <solid android:color="@color/color_b3dddddd" /> 
    <corners android:radius="8dp" /> 
</shape>

没有焦点的按压背景

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <solid android:color="@color/color_b3dddddd" /> 
    <corners android:radius="8dp" /> 
</shape>

但是我们创建selector<item android:state_pressed="true"> 这个没有区分焦点状态的。

解决方案

我们只要在按压的时候设置一下想要的背景,抬起的时候恢复到原来的背景。

1、创建默认的Selector R.drawable.selector_normal

<?xml version="1.0" encoding="utf-8"?><!-- res/drawable/button_selector.xml -->  
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">  

    //按压状态  没有边框
    <item android:state_pressed="true">  
        <shape android:shape="rectangle">  
            <solid android:color="@color/color_b3dddddd" />  
            <corners android:radius="8dp" />  
        </shape> 
    </item>  
    
    //焦点选中状态 
    <item android:state_focused="true">  
        <shape android:shape="rectangle">  
            <stroke android:width="2dp" android:color="@color/color_fff2a900" />  
            <solid android:color="@color/transparent" />  
            <corners android:radius="8dp" />  
        </shape>    
    </item>  
    
    //默认状态
    <item>        
	    <shape android:shape="rectangle">  
            <stroke android:width="2dp" android:color="@color/transparent" />  
            <corners android:radius="8dp" />  
        </shape>    
    </item>
</selector>

2、创建获取焦点时按压背景 R.drawable.shape_rectangle_focus_press

<shape xmlns:android="http://schemas.android.com/apk/res/android"  
    android:shape="rectangle">  
    <stroke  android:width="2dp"  
        android:color="@color/color_fff2a900" />  
    <solid android:color="@color/color_b3dddddd" />  
    <corners android:radius="8dp" />  
</shape>

3、监听遥控器的事件(目前发现两种方式)

  • 重写 View 的onKeyPreIme方法
override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {  
    if (event?.action == KeyEvent.ACTION_DOWN) {  //按压的状态直接设置想要的背景
        when (keyCode) {  
            KeyEvent.KEYCODE_DPAD_CENTER -> {  
                setBackgroundResource(R.drawable.shape_rectangle_focus_press)  
            }  
        }  
    }  
    if (event?.action == KeyEvent.ACTION_UP) {  //抬起恢复默认
        when (keyCode) {  
            KeyEvent.KEYCODE_DPAD_CENTER -> {  
                setBackgroundResource(R.drawable.selector_normal)  
            }  
        }  
    }  
    //这里交回给父类处理就好或者返回false
    //如果返回true 就接收不到点击事件了
    return super.onKeyPreIme(keyCode, event)  
}
  • 给View 的设置 OnKeyListene监听
view.setOnKeyListener { v, keyCode, event ->  
  if (event.action == KeyEvent.ACTION_DOWN) {  
        when (keyCode) {  
            KeyEvent.KEYCODE_DPAD_CENTER -> {  
                setBackgroundResource(R.drawable.shape_rectangle_focus_press)  
            }  
        }  
    }  
    if (event.action == KeyEvent.ACTION_UP) {  
        when (keyCode) {  
            KeyEvent.KEYCODE_DPAD_CENTER -> {
                setBackgroundResource(R.drawable.selector_normal)  
            }  
        }  
    }
    return@setOnKeyListener false  
}