当前位置:   article > 正文

ColorStateList在自定义Drawable中的应用

ColorStateList在自定义Drawable中的应用

ColorStateList的创建

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

  1. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  2. <item android:state_focused="true"
  3. android:color="@color/sample_focused" />
  4. <item android:state_pressed="true"
  5. android:state_enabled="false"
  6. android:color="@color/sample_disabled_pressed" />
  7. <item android:state_enabled="false"
  8. android:color="@color/sample_disabled_not_pressed" />
  9. <item android:color="@color/sample_default" />
  10. </selector>

自定义带状态切换的Drawable

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

注意事项:

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

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

实现实例:

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

  1. @Keep
  2. public class ShadowDrawable extends Drawable {
  3. private final Paint paint;
  4. private float cornerRadius;
  5. private float paddingLeft, paddingRight, paddingTop, paddingBottom;
  6. private ColorStateList colorStateList;
  7. public ShadowDrawable() {
  8. paint = new Paint(Paint.ANTI_ALIAS_FLAG);
  9. }
  10. @Override
  11. public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) throws IOException, XmlPullParserException {
  12. super.inflate(r, parser, attrs, theme);
  13. TypedArray a = r.obtainAttributes(attrs, R.styleable.ShadowDrawable);
  14. float w = a.getDimension(R.styleable.ShadowDrawable_width, 180);
  15. float h = a.getDimension(R.styleable.ShadowDrawable_height, 180);
  16. setBounds(0, 0, (int) w, (int) h);
  17. cornerRadius = a.getDimension(R.styleable.ShadowDrawable_cornerRadius, 60);
  18. paddingLeft = a.getDimension(R.styleable.ShadowDrawable_paddingLeft, 0);
  19. paddingRight = a.getDimension(R.styleable.ShadowDrawable_paddingRight, 0);
  20. paddingTop = a.getDimension(R.styleable.ShadowDrawable_paddingTop, 0);
  21. paddingBottom = a.getDimension(R.styleable.ShadowDrawable_paddingBottom, 0);
  22. colorStateList = a.getColorStateList(R.styleable.ShadowDrawable_color);
  23. a.recycle();
  24. onStateChange(getState());
  25. }
  26. @Override
  27. public boolean isStateful() {
  28. return true;//这里必须为true,才能响应TextView
  29. }
  30. @Override
  31. protected boolean onStateChange(int[] state) {
  32. if (colorStateList != null) {//获取当前状态下的颜色
  33. int color = colorStateList.getColorForState(state, 0);
  34. paint.setColor(color);
  35. paint.setShadowLayer(10, 1, 1, color);
  36. return true;
  37. }
  38. return super.onStateChange(state);
  39. }
  40. @Override
  41. public void draw(@NonNull Canvas canvas) {
  42. Rect bounds = getBounds();
  43. float left = bounds.left + paddingLeft;
  44. float top = bounds.top + paddingTop;
  45. float right = bounds.right - paddingRight;
  46. float bottom = bounds.bottom - paddingBottom;
  47. canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius, paint);
  48. }
  49. @Override
  50. public void setAlpha(int alpha) {
  51. paint.setAlpha(alpha);
  52. }
  53. @Override
  54. public void setColorFilter(@Nullable ColorFilter colorFilter) {
  55. paint.setColorFilter(colorFilter);
  56. }
  57. @Override
  58. public int getOpacity() {
  59. return PixelFormat.OPAQUE;
  60. }
  61. }

attrs.xml中声明ColorStateList:

  1. <declare-styleable name="ShadowDrawable">
  2. <attr name="color" format="color"/>
  3. ...
  4. </declare-styleable>

在xml中使用

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/220777
推荐阅读
相关标签
  

闽ICP备14008679号