为了避免drawable 下面出现一大推的xml ,希望用代码动态创建相应的selector 和 shape ;如果掌握了动态创建drawable,可以在自定义view的时候大有用处,尤其涉及到view的外观变化方面。接下来,开干。
可绘制对象 有颜色列表、形状、状态;这三种是我们最常用的,也还有其他的,不过不常用;下面为示范代码:
形状可绘制对象 GradientDrawable
object GradientDrawableUtil {
fun gradientDrawableCreate(
context: Context,
cornerRadius : Float ?,
@ColorRes solidColor : Int ?, //R.color.colorPrimary
strokeWidth : Int ?,
@ColorRes strokeColor : Int ?,
dashWith : Float = 0F,
dashGap : Float = 0F
) : GradientDrawable{
val gradientDrawable = GradientDrawable()
gradientDrawable.cornerRadius = cornerRadius ?: 0F
// 设置颜色 即为设置 填充色 solid;
if (solidColor != null){
gradientDrawable.setColor(context.resources.getColor(solidColor))
}
if (strokeWidth != null && strokeColor != null){
gradientDrawable.setStroke(strokeWidth, context.resources.getColor(strokeColor), dashWith , dashGap)
}
return gradientDrawable
}
fun gradientDrawableCreate(
context: Context,
cornerRadius : FloatArray, //这个数组长度为8 ,每个角需要两个数值;分别表示左上、右上,右下,左下
@ColorRes solidColor : Int,
strokeWidth : Int,
@ColorRes strokeColor : Int
) : GradientDrawable{
val gradientDrawable = GradientDrawable()
gradientDrawable.cornerRadii = cornerRadius
// 设置颜色 即为设置 填充色 solid;
gradientDrawable.setColor(context.resources.getColor(solidColor))
gradientDrawable.setStroke(strokeWidth, context.resources.getColor(strokeColor))
return gradientDrawable
}
/**
* 虚线的显示问题
* 1。 view高度大于虚线的width
* 2 在xml中添加 android:layerType=“software” 或者 代码中设置 view.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
*/
fun lineDrawableCreate(
context: Context,
strokeWidth : Int = 1,
@ColorRes strokeColor : Int ,
dashWith : Float = 4F,
dashGap : Float = 4F
) : GradientDrawable{
val gradientDrawable = GradientDrawable()
gradientDrawable.shape = GradientDrawable.LINE
gradientDrawable.setStroke(strokeWidth, context.resources.getColor(strokeColor), dashWith , dashGap)
return gradientDrawable
}
}
颜色和状态
public class StateDrawableUtil {
/**
* 示范代码
*
* 这里 state[2] = new int[]{-android.R.attr.state_checked}; 添加负号 表示 false 的意思
* @param context
* @return
*/
public static StateListDrawable getStateListDrawable(Context context){
StateListDrawable stateListDrawable = new StateListDrawable();
int [][] state = new int[4][];
state[0] = new int[]{android.R.attr.state_checked};
state[1] = new int[]{android.R.attr.state_selected};
state[2] = new int[]{-android.R.attr.state_checked};
state[3] = new int[]{-android.R.attr.state_selected};
//
//stateListDrawable.addState(state[0], context.getResources().getDrawable(R.color.colorPrimary));
//stateListDrawable.addState(state[0], context.getResources().getDrawable( 其他的 drawable 文件, R.drawable.selector));
stateListDrawable.addState(state[0], context.getResources().getDrawable(R.drawable.deduct_checked));
stateListDrawable.addState(state[1], context.getResources().getDrawable(R.drawable.deduct_checked));
stateListDrawable.addState(state[2], context.getResources().getDrawable(R.drawable.deduct_uncheck));
stateListDrawable.addState(state[3], context.getResources().getDrawable(R.drawable.deduct_uncheck));
return stateListDrawable;
}
/**
* 获取stateList 工具类
* @param state
* @param drawables
* @return
*/
public static StateListDrawable getStateListDrawable(int [][] state, Drawable[] drawables){
if (drawables == null || drawables.length == 0){
return null;
}
if (state == null || state.length == 0){
return null;
}
if (drawables.length != state.length){
return null;
}
StateListDrawable stateListDrawable = new StateListDrawable();
for (int i = 0; i < drawables.length; i++) {
stateListDrawable.addState(state[i], drawables[i]);
}
return stateListDrawable;
}
/**
* 示范代码 获取颜色
* 注意 颜色 要是这样使用 context.getResources().getColor(R.color.colorAccent), 不能传递一个 R.color.colorAccent
* 这个方法可以加给 textView ,不过要添加点击事件,否则没有办法触发press 事件;或者用其他的按钮控制focus 状态
* 这样没有作用
* @param context
* @return
*/
public static ColorStateList getColorStates(Context context){
int [][] states = new int[4][];
states[0] = new int[]{android.R.attr.state_pressed};
states[1] = new int[]{android.R.attr.state_focused};
states[2] = new int[]{-android.R.attr.state_pressed};
states[3] = new int[]{-android.R.attr.state_focused};
int [] colors = new int[]{
context.getResources().getColor(R.color.colorAccent),
context.getResources().getColor(R.color.colorAccent),
context.getResources().getColor(R.color.colorPrimary),
context.getResources().getColor(R.color.colorPrimary)
};
ColorStateList colorStateList = new ColorStateList( states, colors);
//colorStateList.valueOf(R.color.colorAccent);
return colorStateList;
}
/**
* 抽象颜色工具类 但是没有什么用
* @param state
* @param colors
* @return
*/
public static ColorStateList getColorStates(int [][] state, int [] colors){
if (colors == null || colors.length == 0){
return null;
}
if (state == null || state.length == 0){
return null;
}
if (colors.length != state.length){
return null;
}
return new ColorStateList( state, colors);
}
}
注释和用法都在里面写的比较详细了,欢迎使用。
对于selector的状态的使用,可以 参考 https://blog.youkuaiyun.com/sjh_389510506/article/details/105270753 ;如果想看 xml 中shape的 属性,可以看 https://blog.youkuaiyun.com/sjh_389510506/article/details/85134904