1.Drawable
Android中,所有能显示出来的都抽象定义为一个父类Drawable[可绘制的图形], 包括但不限于图片、色块、画板、背景等。
1.1 Drawable资源
- drawable文件放在res目录的各个drawable目录下;
- \res\drawable一般放的是描述性的xml文件;
- 图片文件一般放在具体分辨率的mipmap-xdpi或drawable-xdpi目录下;
1.2 Drawable多状态图形
StateListDrawable可以根据不同的手势状态变化图形,对应xml中的selector
<?xml version="1.0" encoding="utf-8"?>
<!-- android:enterFadeDuration="200" 、android:exitFadeDuration="200"
进入新状态或退出旧状态时会有一个200毫秒的渐变动画
android:dither="true"
表示是否对图像进行抖动处理。当图像的bit-color较少时,通过颜色值的抖动来增加可用颜色数量,并保持较好的显示效果
android:constantSize="true"
当选择器各个状态的图片大小不一时,设置为 true表示以最大的图片的尺寸显示,设置为false以默认的图片的尺寸显示
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 其他状态的item drawable 须置前 -->
<item android:state_pressed="true" android:drawable="@drawable/shape_btn_blue_radius5"/>
<!-- 默认状态的item drawable 必须放在最后-->
<item android:drawable="@drawable/shape_btn_gray_radius5"/>
</selector>
引用的 shape_btn_blue_radius5.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp" />
<solid android:color="@android:color/holo_blue_light" />
</shape>
引用的 shape_btn_gray_radius5.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp" />
<solid android:color="@android:color/darker_gray" />
</shape>
1.3 多状态非引用
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 一般用于单选框RadioButton、复选框CheckBox,
图形设置于android:drawableLeft -->
<!-- <item android:state_checkable="true">-->
<!-- <shape>-->
<!-- <corners android:radius="5dp"/>-->
<!-- <stroke android:color="@android:color/holo_orange_light" android:width="1dp"/>-->
<!-- <solid android:color="@android:color/holo_green_dark"/>-->
<!-- </shape>-->
<!-- </item>-->
<!-- <item android:state_selected="true">-->
<!-- <shape>-->
<!-- <corners android:radius="5dp"/>-->
<!-- <stroke android:color="@android:color/holo_orange_light" android:width="1dp"/>-->
<!-- <solid android:color="@android:color/holo_green_dark"/>-->
<!-- </shape>-->
<!-- </item>-->
<!-- <item android:state_focused="true">-->
<!-- <shape>-->
<!-- <corners android:radius="5dp"/>-->
<!-- <stroke android:color="@android:color/holo_orange_light" android:width="1dp"/>-->
<!-- <solid android:color="@android:color/holo_green_dark"/>-->
<!-- </shape>-->
<!-- </item>-->
<item android:state_pressed="true">
<shape>
<corners android:radius="8dp"/>
<solid android:color="@android:color/holo_blue_light"/>
</shape>
</item>
<item>
<shape>
<corners android:radius="5dp"/>
<stroke android:color="@android:color/holo_orange_light" android:width="1dp"/>
<solid android:color="@android:color/holo_red_dark"/>
</shape>
</item>
</selector>
2.shape :Android中最常用的xml绘图
2.1 先举例
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp" />
<solid android:color="@android:color/holo_blue_light" />
</shape>
2.2 详解
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- android:shape 设置形状 :
rectangle 矩形 【默认】
oval 椭圆
line 直线
ring 圆环-->
<!-- 下面的属性只有在android:shape="ring"时可用:
android:innerRadius: 像素类型,内圆的半径 ,10dp。
android:innerRadiusRatio: 浮点型,以环的宽度比率来表示内圆的半径。例如,如果android:innerRadiusRatio="3",表示内圆半径等于环的宽度(即外圆直径)除以3。如已设置android:innerRadius则不需设置本属性
android:thickness: 像素类型,环的厚度 ,10dp
android:thicknessRatio: 浮点型,以环的宽度比率来表示环的厚度。例如,如果android:thicknessRatio="2",那么环的厚度就等于环的宽度除以2。如已设置android:thickness则不需设置本属性
android:useLevel: 布尔类型,如果当做是LevelListDrawable使用时值为true,否则为false( 一般情况必须设置为false,不然ring无法显示)。 -->
<!-- =============================================================================== -->
<!-- =============================================================================== -->
<!-- =============================================================================== -->
<!-- 4个角统一圆角值 -->
<!-- <corners android:radius="5dp" />-->
<!-- 4个角 逐一设置圆角值 -->
<corners
android:bottomLeftRadius="15dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="15dp" />
<!-- android:angle: 整型,渐变的起始角度。0值时表示时钟的九点位置,其值增大表示往逆时针方向旋转。例如值为90表示时钟六点位置,值为180表示时钟三点位置,值为270表示时钟零点/十二点位置
android:centerX: 浮点型,圆心的X坐标。当android:type="linear"时不可用
android:centerY: 浮点型,圆心的Y坐标。当android:type="linear"时不可用
android:gradientRadius: 整型,渐变的半径。当android:type="radial"时才需要设置该属性
android:centerColor: 颜色类型,渐变的中间颜色
android:startColor: 颜色类型,渐变的起始颜色
android:endColor: 颜色类型,渐变的终止颜色
android:type: 字符串类型,渐变类型。为linear表示线性渐变(默认值),为radial表示放射渐变(起始颜色就是圆心颜色),为sweep表示滚动渐变(即一个线段以某个端点为圆心做360度旋转)
android:useLevel: 布尔类型,设置为true无渐变,false有渐变色。如果要使用LevelListDrawable对象,就要设置为true -->
<gradient
android:angle="90"
android:endColor="#000000ff"
android:startColor="#ffff0000" />
<!-- 填充颜色-->
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp" />
<!--无size节点表示长宽自适应,一般不设置size 节点-->
<size
android:width="125dp"
android:height="45dp" />
<!-- 使用 gradient,solid,谁在后面谁生效-->
<solid android:color="@android:color/darker_gray" />
<!-- width:描边的线宽
color:描边的颜色
dashWidth:值大于0 :描边改为虚线线段,单个线段长度
dashGap:值大于0:描边改为虚线线段 ,虚线线段的间距-->
<stroke
android:width="2dp"
android:color="@android:color/holo_red_dark"
android:dashWidth="5dp"
android:dashGap="10dp" />
</shape>
3.selector扩展
3.1 文字颜色选择器,要使用android:color="ARGB|RGB颜色值"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#00FF00" android:state_pressed="true" />
<item android:color="#0000FF" />
</selector>
3.2 使用 animated-rotate
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
<item android:state_pressed="true">
<animated-rotate android:drawable="@drawable/ic_test" android:pivotX="50%" android:pivotY="50%"/>
</item>
<item android:drawable="@drawable/ic_test" />
</selector>
3.3 java代码动态创建selector
public static void createSelector(Context context, View view, @DrawableRes int... resIds) {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable drawablePre = ContextCompat.getDrawable(context, resIds[0]);
Drawable drawableDef = ContextCompat.getDrawable(context, resIds[1]);
stateListDrawable.addState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}, drawablePre);
stateListDrawable.addState(new int[0], drawableDef);
stateListDrawable.setState(new int[0]);
stateListDrawable.setEnterFadeDuration(200);
stateListDrawable.setExitFadeDuration(200);
view.setBackground(stateListDrawable);
}
3.4 java代码动态创建selector辅助类
public class SelectorHelper {
//常用状态数组
public static final int[] STATE_DEFAULT = new int[0];
public static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled};
public static final int[] STATE_SELECTED = new int[]{android.R.attr.state_selected};
public static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};
public static final int[] STATE_UNCHECKED = new int[]{-android.R.attr.state_checked};
public static final int[] STATE_DISABLED = new int[]{-android.R.attr.state_enabled};
public static final int[] STATE_FOCUSED = new int[]{android.R.attr.state_focused};
/**
* 动态创建一个简单的选择器
* @param context
* @param view
* @param resId
*/
public static void createSelector(Context context, View view, @DrawableRes int... resId) {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable drawablePre = ContextCompat.getDrawable(context, resId[0]);
Drawable drawableDef = ContextCompat.getDrawable(context, resId[1]);
stateListDrawable.addState(STATE_PRESSED, drawablePre);
stateListDrawable.addState(new int[0], drawableDef);
stateListDrawable.setState(new int[0]);
stateListDrawable.setEnterFadeDuration(200);
stateListDrawable.setExitFadeDuration(200);
view.setBackground(stateListDrawable);
}
/**
* 通过对图片的着色创建选择器
* @param context
* @param view
* @param isVector
* @param resId
*/
public static void createSelector(Context context, View view, boolean isVector, @DrawableRes int resId) {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable drawableSrc;
if (isVector) {
drawableSrc = VectorDrawableCompat.create(context.getResources(), resId, context.getTheme());
} else {
drawableSrc = ContextCompat.getDrawable(context, resId);
}
stateListDrawable.addState(STATE_PRESSED, drawableSrc);
stateListDrawable.addState(new int[0], drawableSrc);
stateListDrawable.setState(new int[0]);
Drawable wrapDrawable = DrawableCompat.wrap(stateListDrawable);
ColorStateList colorStateList = new ColorStateList(new int[][]{
STATE_PRESSED,
new int[0]
}, new int[]{0XFFFF0000, 0xFF00FF00});
DrawableCompat.setTintList(wrapDrawable, colorStateList);
view.setBackground(stateListDrawable);
}
/**
* 文字颜色选择器
* @param v
*/
public static void createSelector(TextView v) {
ColorStateList colorStateList = new ColorStateList(new int[][]{
STATE_PRESSED,
new int[0]
}, new int[]{Color.CYAN, Color.BLACK});
v.setTextColor(colorStateList);
}
/**
*
* @param context 上下文
* @param view View
* @param isVector 是否为矢量图
* @param resId 图片数组
*/
public static void createSelector(Context context, View view, boolean isVector, @DrawableRes int... resId) {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable drawableDis;
Drawable drawablePre;
Drawable drawableSel;
Drawable drawableDef;
if (isVector) {
drawableDis = VectorDrawableCompat.create(context.getResources(), resId[0], context.getTheme());
drawablePre = VectorDrawableCompat.create(context.getResources(), resId[1], context.getTheme());
drawableSel = VectorDrawableCompat.create(context.getResources(), resId[2], context.getTheme());
drawableDef = VectorDrawableCompat.create(context.getResources(), resId[3], context.getTheme());
} else {
drawableDis = ContextCompat.getDrawable(context, resId[0]);
drawablePre = ContextCompat.getDrawable(context, resId[1]);
drawableSel = ContextCompat.getDrawable(context, resId[2]);
drawableDef = ContextCompat.getDrawable(context, resId[3]);
}
stateListDrawable.addState(STATE_DISABLED, drawableDis);
stateListDrawable.addState(STATE_PRESSED, drawablePre);
stateListDrawable.addState(STATE_SELECTED, drawableSel);
stateListDrawable.addState(STATE_DEFAULT, drawableDef);
stateListDrawable.setState(STATE_DEFAULT);
stateListDrawable.setEnterFadeDuration(200);
stateListDrawable.setExitFadeDuration(200);
view.setBackground(stateListDrawable);
}
}