1 概述
1.1 编写目的
学习Android图形选择Selector相关的知识,记录下来,方便后续学习及查询。
2 Selector图形(Drawable)
Android上Selector有selector和item两种属性,其中selector为一级属性,其余为item子属性,子属性可以选择定义。基本结构如下图:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item />
</selector>
2.1 Selector属性
Selector共包含以下属性:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:visible="true"
android:enterFadeDuration="1000"
android:exitFadeDuration="1000"
android:variablePadding="true"
android:autoMirrored="true"
android:constantSize="true">
Dither:值为“true”时,将在位图的像素配置与屏幕不同时(例如:ARGB 8888 位图和 RGB 565 屏幕)启用位图的抖动;值为“false”时则停用抖动。默认值为 true。
Visible:设置初始的可见性状态,默认为false。
ExitFadeDuration:状态改变时,旧状态消失时的淡出时间,单位毫秒。
EnterFadeDuration:状态改变时,新状态展示时的淡入时间,单位毫秒。
VariablePadding:如果可绘制对象的内边距,应根据选择的当前状态而变化,则值为“true”;如果内边距应保持不变(基于所有状态的最大内边距),则值为“false”。启用此功能要求您在状态变更时处理执行布局,这通常不受支持。默认值为 false。
AautoMirrored:设置图片是否需要镜像反转,当布局方向是RTL,即从右到左布局时才有用。
ConstantSize:可绘制对象报告的内部大小,在状态变更时保持不变,则值为“true”(大小是所有状态的最大值);如果大小根据当前状态而变化,则值为“false”。默认值为 false。
2.2 Item属性
Item共包含以下属性:
<item android:drawable="@drawable/my_selected"
android:state_accelerated="true"
android:state_activated="true"
android:state_active="true"
android:state_checkable="true"
android:state_checked="true"
android:state_drag_can_accept="true"
android:state_drag_hovered="true"
android:state_enabled="true"
android:state_first="true"
android:state_focused="true"
android:state_hovered="true"
android:state_last="true"
android:state_middle="true"
android:state_pressed="true"
android:state_selected="true"
android:state_single="true"
android:state_window_focused="true">
<animated-rotate />
<animated-selector />
<animation-list />
<bitmap />
<clip />
<color />
<inset />
<layer-list />
<level-list />
<nine-patch />
<ripple />
<rotate />
<scale />
<selector />
<shape />
<transition />
</item>
其中一级属性如下:
Drawable:引用要插入的可绘制对象资源,可以是图片和颜色。列如:android:drawable="@drawable/my_selected"、 android:drawable="#888888"或android:drawable=" @color/gray"。
State_accelerated:判断对象是否启用硬件加速时使用此项目["true" | "false"]。
State_activated:判断对象是否具激活作为持续选择时使用此项目["true" | "false"]。
State_active:判断对象是否激活时使用此项目["true" | "false"]。
State_checkable:判断是否可选中对象时使用此项目["true" | "false"]。
State_checked:判断是否选中对象时使用此项目["true" | "false"]。
State_drag_can_accept:判断对象是否可以拖拽时使用此项目["true" | "false"]。
State_drag_hovered:判断对象拖拽时上面是否有View时使用此项目["true" | "false"]。
State_enabled:判断是否启用对象是使用此项目(是否能够接收触摸/点击事件)["true" | "false"]。
State_first:判断对象是否处于开始状态时使用此项目["true" | "false"]。
State_focused:判断对象是否具有焦点时使用此项目["true" | "false"]。
State_hovered:判断是否将光标停在对象上时使用此项目["true" | "false"]。
State_last:判断对象是否处于结束状态时使用此项目["true" | "false"]。
State_middle:判断对象是否处于中间状态时使用此项目["true" | "false"]。
State_pressed:判断是否按下对象时使用此项目["true" | "false"]。
State_selected:判断是否选择对象时使用此项目["true" | "false"],对应View.setSelected(true)、View.setSelected(false)。
State_single:判断对象或父对象是否处于选择状态时使用此项目["true" | "false"]。
State_window_focused:判断对象所在窗口是否有焦点上时使用此项目["true" | "false"]。
2.3 Item下级属性
如2.2所示Item共包含animated-rotate、animated-selector、animation-list、bitmap、clip、color、inset、layer-list、level-list、nine-patch、ripple、rotate、scale、selector、shape、transition等下级属性:
Bitmap: 详情Bitmap图形。
Shape: 详情自定义图形。
Layer-list: 详情图形层叠。
部分属性请看下面第5。
2.4 Item常用属性
一般在按压、选择、焦点状态显示一种效果,其它显示一种效果。创建my_selected.xml和my_unselected.xml除颜色外,其它一样,my_selected.xml如下所示:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFF00"
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
创建my_selector.xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
<item android:drawable="@drawable/my_selected" android:state_pressed="true" />
<item android:drawable="@drawable/my_selected" android:state_checked="true" />
<item android:drawable="@drawable/my_selected" android:state_focused="true" />
<item android:drawable="@drawable/my_unselected"/>
</selector>
2.5 资源创建
在res/drawable/下创建 my_selector.xml文件,内容如2.4所示。
3 Selector颜色(Color)
3.1 Selector属性
选择颜色时,selector没有包含属性。
3.2 Item属性
Item共包含以下属性:
<item android:color="#888888"
android:state_accelerated="true"
android:state_activated="true"
android:state_active="true"
android:state_checkable="true"
android:state_checked="true"
android:state_drag_can_accept="true"
android:state_drag_hovered="true"
android:state_enabled="true"
android:state_first="true"
android:state_focused="true"
android:state_hovered="true"
android:state_last="true"
android:state_middle="true"
android:state_pressed="true"
android:state_selected="true"
android:state_single="true"
android:state_window_focused="true"/>
Color:引用的颜色,android:color ="#888888"或android:color=" @color/gray"。
其它属性和图形的一致。
3.3 Item常用属性
常用属性同图形一致。创建color_selector.xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FFFF00" android:state_selected="true"/>
<item android:color="#FFFF00" android:state_pressed="true" />
<item android:color="#FFFF00" android:state_checked="true"/>
<item android:color="#FFFF00" android:state_focused="true"/>
<item android:color="#888888"/>
</selector>
3.4 资源创建
在res/color/下创建 color_selector.xml文件,内容3.3所示。
4 Selector应用
使用2、3中的图形和颜色选择。布局setector_view.Xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingTop="200dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/selector_button1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:background="@drawable/my_selector"/>
<Button
android:id="@+id/selector_button2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:textSize="20dp"
android:text="@string/color_selector_test"
android:textColor="@color/color_selector"/>
</LinearLayout>
代码片段:
public class SetectorActivity extends Activity{
private Button myButton1, myButton2, myButton3;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setector_view);
myButton1 = (Button) findViewById(R.id.selector_button1);
myButton2 = (Button) findViewById(R.id.selector_button2);
myButton1.setOnClickListener(myOnClickListener);
myButton2.setOnClickListener(myOnClickListener);
}
View.OnClickListener myOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
myButton1.setSelected(false);
myButton2.setSelected(false);
v.setSelected(true);
}
};
}
效果如下:
![](https://img-my.csdn.net/uploads/201801/12/1515727546_8025.gif)
5 Item下级属性
5.1 Animated-rotate属性(旋转)
旋转动画,在item中该属性包含以下几个属性,修改my_selector.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
android:state_focused="true" />
<item >
<animated-rotate
android:drawable="@drawable/animated_rotate_test"
android:pivotX="250"
android:pivotY="250"
android:visible="true" />
</item>
</selector>
Drawable:指向图片资源。
PivotX:旋转中心X坐标,布局控件的宽为X,左上为0点。
PivotY:旋转中心Y坐标,布局控件的高为Y,左上为0点。
Visible:是否可见["true" | "false"]。
其中animated_rotate_test.xml如下,图形居中,白色为参考线,实际显示时删除了没有:
修改setector_view.Xml如下,Button控件高宽改为500px,这样animated-rotate中pivotX和PivotY刚好在中间:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingTop="200dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/selector_button1"
android:layout_width="500px"
android:layout_height="500px"
android:layout_gravity="center"
android:background="@drawable/my_selector"/>
<Button
android:id="@+id/selector_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20dp"
android:text="@string/color_selector_test"
android:textColor="@color/color_selector"/>
</LinearLayout>
其它文件不变,效果如下:
![](https://img-my.csdn.net/uploads/201801/12/1515727546_8999.gif)
5.2 Color属性
<item>
<color
android:color="@color/green"/>
</item>
只有一项属性,设置颜色。
5.3 Clip属性(截取)
截取显示,共用三个属性drawable(图片资源)、clipOrientation(截取方向)、gravity(重心),修改my_selector.xml如下
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
<item >
<clip
android:drawable="@drawable/my_unselected"
android:clipOrientation="horizontal"
android:gravity="center"/>
</item>
</selector>
修改setector_view.Xml如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingTop="200dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/selector_button1"
android:layout_width="500px"
android:layout_height="500px"
android:layout_gravity="center"
android:src="@drawable/my_selector"/>
<Button
android:id="@+id/selector_button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20dp"
android:text="@string/color_selector_test"
android:textColor="@color/color_selector"/>
</LinearLayout>
修改代码:
public class SetectorActivity extends Activity{
private Button myButton1, myButton2;
private ImageView myImageView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setector_view);
myImageView = (ImageView) findViewById(R.id.selector_button1);
myButton2 = (Button) findViewById(R.id.selector_button2);
myImageView.setOnClickListener(myOnClickListener);
myButton2.setOnClickListener(myOnClickListener);
}
View.OnClickListener myOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
myImageView.setSelected(false);
myButton2.setSelected(false);
if (R.id.selector_button2 == v.getId()) {
Drawable drawable = myImageView.getDrawable();
drawable.setLevel(drawable.getLevel() + 500);
}
v.setSelected(true);
}
};
}
效果如下:
![](https://img-my.csdn.net/uploads/201801/12/1515727547_1371.gif)
5.4 Scale属性(缩放)
缩放显示,修改my_selector.xml,属性如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
<item >
<scale
android:drawable="@drawable/my_unselected"
android:scaleGravity="center"
android:level="1"
android:useIntrinsicSizeAsMinimum="false"
android:scaleHeight="100%"
android:scaleWidth="100%"/>
</item>
</selector>
Drawable:指向图片资源。
ScaleGravity:缩放重心。
Level: 缩放比例,通过代码drawable.setLevel实时修改缩放比例(代码设置时UseIntrinsicSizeAsMinimum必须为false)。
UseIntrinsicSizeAsMinimum:是否使用原始大小作为最小高宽,如果为true,将不能通过setLevel改变比例。
ScaleHeight:高度缩放比例,[0%~100%],表示从高度多少开始缩放,0%表示起始高度为原图高度(不缩放),100%表示起始高度为0。
ScaleWidth:宽度缩放比例,[0%~100%],表示从宽度多少开始缩放。
其它控件和代码同5.5,效果如下:
![](https://img-my.csdn.net/uploads/201801/12/1515727548_4227.gif)
5.5 Rotate属性(旋转)
旋转显示,修改my_selector.xml,属性如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
<item >
<rotate
android:drawable="@drawable/my_unselected"
android:fromDegrees="0"
android:toDegrees="180"
android:pivotX="250"
android:pivotY="250"
android:visible="true"/>
</item>
</selector>
Drawable:指向图片资源。
FromDegrees:旋转的开始角度。
ToDegrees:旋转的结束角度。
PivotX:旋转中心X坐标,布局控件的宽为X,左上为0点。
PivotY:旋转中心Y坐标,布局控件的高为Y,左上为0点。
Visible:是否可见["true" | "false"]。
5.6 Ripple属性(水波)
水波效果,修改my_selector.xml,属性如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true">
<ripple
android:color="@color/red"
android:radius="10px">
<item android:drawable="@color/lb_grey"/>
</ripple>
</item>
<item android:drawable="@drawable/my_unselected"/>
</selector>
Color:水波颜色。
Radius:水波半径。
其它同代码同5.5,效果如下:
![](https://img-my.csdn.net/uploads/201801/12/1515727548_4063.gif)
5.7 Inset属性(边距等比例缩小)
按照边距等比例缩小,修改my_selector.xml,属性如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/my_selected" android:state_selected="true"/>
<item >
<inset
android:drawable="@drawable/my_unselected"
android:inset="50px"
android:insetTop="40px"
android:insetBottom="20px"
android:insetLeft="10px"
android:insetRight="0px"
android:visible="true">
</inset>
</item>
</selector>
Drawable:指向图片资源。
Inset:与四周的距离。
InsetTop:与顶部的距离。
InsetBottom:与底部的距离。
insetLeft:与左边的距离。
insetRight:与右边的距离。
Visible:是否可见["true" | "false"]。
Inset和InsetTop、InsetBottom、insetLeft、insetRight同时设置时,单独设置有效,修改setector_view.Xml中背景用于对比,效果如下: