代码创建可绘制对象 Drawable

本文介绍如何通过代码动态创建Drawable对象,包括GradientDrawable和StateListDrawable,用于自定义View的外观变化,如边框、圆角、颜色及状态选择器。提供了实用的代码示例,帮助开发者灵活控制UI元素的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了避免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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值