一、前期基础知识储备
在前一节内容《Android XML绘图精炼详解第(一)课:Shape解析和示例》中,我们学习了Android XML绘图的第一种技能——Shape形状,这节讲解,我们来学习第二种技能——Selector 即状态选择器,Selector的作用在于帮助开发者实现静态绘图中的事件反馈,通过给不同的事件设置不同的图像,从而在程序中根据用户输入,返回不同的结果。
参见官方文档:
A selector may be created by invoking the open method of this class, which will use the system's default selector provider to create a new selector. A selector may also be created by invoking the openSelector method of a custom selector provider. A selector remains open until it is closed via its close method.
由官方文档,我们可知所谓状态选择器,就是控件(view或者viewgroup)根据不同的选定状态来定义不同的现实效果,我们可以在指定的状态下,切换控件的背景属性(background),从而达到效果绚丽的目的。
二、上代码,具体实现
本节代码,结合了前面第一篇文章的Shape,来联合实现一个切换效果(实际开发中很常用)
参见代码;
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#FF0000" />
<corners android:radius="5dip" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="5dip" />
<padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
</shape>
</item>
</selector>
使用时,直接作为background属性设置给一个Button即可:
<Button
android:id="@+id/shape_shadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_shadow"
android:text="航天母舰" />
Selector常用属性集合:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
//默认时的背景图片
<item android:drawable="@drawable/gray"/>
//没有焦点时的背景图片
<item android:state_window_focused="false"
android:drawable="@drawable/choosed"/>
//非触摸模式下获得焦点并单击时的背景图片
<item android:state_focused="true"
android:state_pressed="true"
android:drawable="@drawable/yellow"/>
//触摸模式下单击时的背景图片
<item android:state_focused="false"
android:state_pressed="true"
android:drawable="@drawable/none"/>
//选中时的图片背景
<item android:state_selected="true"
android:drawable="@drawable/red"/>
//获得焦点时的图片背景
<item android:state_focused="true"
android:drawable="@drawable/red"/>
</selector>
也可以在设置选择器的同时,为shape设置阴影:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<layer-list>
<!-- 相当于padding -->
<item android:left="4dp" android:top="4dp">
<shape>
<solid android:color="#ff58bb52" />
<corners android:radius="3dp"/>
</shape>
</item>
</layer-list>
</item>
<item>
<layer-list>
<!-- SHADOW LAYER -->
<item >
<shape>
<solid android:color="#33000000" />
<corners android:radius="3dp"/>
</shape>
</item>
<!-- CONTENT LAYER -->
<!-- 相当于padding -->
<item android:bottom="1dp" android:right="1dp"
android:left="1dp" android:top="1dp">
<shape>
<solid android:color="#ffffff" />
<corners android:radius="3dp"/>
</shape>
</item>
</layer-list>
</item>
</selector>
运行效果如图示:
小结:上述的方法可以帮助开发者快速制作View的触摸反馈。通过配置不同的触发事件,Selector可以自动选择不同的图片。特别是在自定义Button中,我们就不用在使用原生Button单调的背景,而使用Selector特别定制的背景。不用在程序代码中修改点击的逻辑,就能完美实现触摸反馈。
延伸:如果,控件不只是一个Button,而是一个ImageButton,此时,按压要求,也不仅仅只是颜色的变化,而是按压时图片发生变化,从一张图片变为另外一张,这个时候就不能用Selector进行实现了。代码如下:
compareBtn = (ImageButton) findViewById(R.id.ib_compare);
compareBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
toOriginal();
compareBtn.setImageResource(R.drawable.ic_compare_pressed);
break;
case MotionEvent.ACTION_UP:
toNormal();
compareBtn.setImageResource(R.drawable.ic_compare);
break;
default:
break;
}
return true;
}
});
我们通过为ImageButton设置onTouch()监听来实现,手指按压down时设置一张图片,手指抬起up时设置另外一张图片。