ColorStateList在自定义Drawable中的应用

ColorStateList的创建

ColorStateList中包含一系列状态及颜色的组合,可以根据View不同的状态显示不同的颜色,通常通过xml创建:在res目录中的color目录(如没有可以自己创建)中,右键-New->Color Resource File 创建color资源文件,xml中的内容类似下面这种:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"
          android:color="@color/sample_focused" />
    <item android:state_pressed="true"
          android:state_enabled="false"
          android:color="@color/sample_disabled_pressed" />
    <item android:state_enabled="false"
          android:color="@color/sample_disabled_not_pressed" />
    <item android:color="@color/sample_default" />
  </selector>

自定义带状态切换的Drawable

Drawable是抽象类,需要重写其中的抽象方法,最主要的是draw()方法,在这里实现绘制自定义的Drawable;除此之外,inflate()基本也是必须要重写的,可以结合 declare-styleable标签声明的自定义属性,获取自定义属性的值,ColorStateList也可以通过这种方式获取。

注意事项:

1. 为了在View的状态变化后自动响应,还需要重写onStateChange()和isStateful()两个方法。在onStateChange()中,根据状态获取当前应该显示的颜色;isStateful()方法,Drawable默认返回false,需要返回true才能响应View。

2. 如果考虑混淆,需要加混淆例外,否则xml找不到自定义Drawable类。

实现实例:

下面的自定义Drawable实现了自定义阴影效果

@Keep
public class ShadowDrawable extends Drawable {
    private final Paint paint;
    private float cornerRadius;
    private float paddingLeft, paddingRight, paddingTop, paddingBottom;
    private ColorStateList colorStateList;

    public ShadowDrawable() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    @Override
    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) throws IOException, XmlPullParserException {
        super.inflate(r, parser, attrs, theme);
        TypedArray a = r.obtainAttributes(attrs, R.styleable.ShadowDrawable);
        float w = a.getDimension(R.styleable.ShadowDrawable_width, 180);
        float h = a.getDimension(R.styleable.ShadowDrawable_height, 180);
        setBounds(0, 0, (int) w, (int) h);
        cornerRadius = a.getDimension(R.styleable.ShadowDrawable_cornerRadius, 60);
        paddingLeft = a.getDimension(R.styleable.ShadowDrawable_paddingLeft, 0);
        paddingRight = a.getDimension(R.styleable.ShadowDrawable_paddingRight, 0);
        paddingTop = a.getDimension(R.styleable.ShadowDrawable_paddingTop, 0);
        paddingBottom = a.getDimension(R.styleable.ShadowDrawable_paddingBottom, 0);
        colorStateList = a.getColorStateList(R.styleable.ShadowDrawable_color);
        a.recycle();
        onStateChange(getState());
    }

    @Override
    public boolean isStateful() {
        return true;//这里必须为true,才能响应TextView
    }

    @Override
    protected boolean onStateChange(int[] state) {
        if (colorStateList != null) {//获取当前状态下的颜色
            int color = colorStateList.getColorForState(state, 0);
            paint.setColor(color);
            paint.setShadowLayer(10, 1, 1, color);
            return true;
        }
        return super.onStateChange(state);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        Rect bounds = getBounds();
        float left = bounds.left + paddingLeft;
        float top = bounds.top + paddingTop;
        float right = bounds.right - paddingRight;
        float bottom = bounds.bottom - paddingBottom;
        canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius, paint);
    }

    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        paint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.OPAQUE;
    }
}

attrs.xml中声明ColorStateList:

<declare-styleable name="ShadowDrawable">
        <attr name="color" format="color"/>
        ...
    </declare-styleable>

在xml中使用

在res/drawable目录中新建xml资源文件,指定class属性

<drawable xmlns:app="http://schemas.android.com/apk/res-auto"
    class="com.xxx.ShadowDrawable"
    app:color="@color/color_shadow_red"
    app:cornerRadius="20dp"
    app:paddingBottom="10dp"
    app:paddingLeft="5dp"
    app:paddingRight="5dp"
    app:paddingTop="10dp" />

相关推荐

  1. ColorStateList定义Drawable应用

    2024-03-10 07:00:06       23 阅读
  2. Androiddrawable

    2024-03-10 07:00:06       12 阅读
  3. 如何Python定义异常?

    2024-03-10 07:00:06       9 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-10 07:00:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-10 07:00:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-10 07:00:06       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-10 07:00:06       20 阅读

热门阅读

  1. 初识 Verilog

    2024-03-10 07:00:06       20 阅读
  2. 区块链web3智能合约Solidity学习资源整理

    2024-03-10 07:00:06       21 阅读
  3. 【MySQL 系列】在 Ubuntu 上安装 MySQL

    2024-03-10 07:00:06       22 阅读
  4. bash 给表格加列名

    2024-03-10 07:00:06       18 阅读
  5. C++ 友元

    2024-03-10 07:00:06       27 阅读