一个 selector工具类

你是否曾抱怨过产品经理,为什么一个app里面按钮正常/按下状态颜色不统一起来? 
你是否曾埋怨过UI,为什么不同地方输入框的颜色、圆角和聚焦字体颜色不一样? 
你是否曾因为为了避免少些一个selector的.xml文件而手动的去控制TextView在选中/非选中状态下的颜色? 
你是否曾因为drawable目录下selector,shape文件太多,第二次要用却忘了以前有没有定义过又找不到而苦恼?

今天,我便是为解决此问题而来

  • 传统方式对于Button背景色不同状态下以XML文件的方式的定义

通常状态下我们对于Button的按压状态下和非按压状态下我们需要两种不同的背景 
一般都是通过xml文件来书写Selector方式来实现的:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/blue_bg_dark" android:state_pressed="true"/>
    <item android:drawable="@drawable/blue_bg" android:state_pressed="false"/>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

当然了其实后面一个item不用写state_pressed=”false”也无妨(而且正确的写法,selector最后一个item就应该不写state),这是以图片的方式来定义不同状态下的背景,当然你也可是换成颜色的方式。

不过这两种方式有个共同的缺点,就是你无法去定义item的形状。图片是什么形状,就是什么形状。通常设计给我们的按钮、输入框通常都会是一个圆角的矩形,这个时候我们就需要用到Shape。这里就以EditText的圆角背景为例,通常我们会这么定义:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="true">
        <shape android:shape="rectangle">
            <corners android:radius="10dp"/>
            <stroke android:width="1dp" android:color="@color/red"/>
            <solid android:color="@color/transparent"/>
        </shape>
    </item>

    <item android:state_focused="false">
        <shape android:shape="rectangle">
            <corners android:radius="10dp"/>
            <stroke android:width="1dp" android:color="@color/gray"/>
            <solid android:color="@color/transparent"/>
        </shape>
    </item>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这样便是定义了一个圆角半径为10dp的矩形背景框,当EditText获得焦点的时候边框会呈现红色,没有获取焦点时会呈现灰色,需要两个或以上各EditText一起使用时可以看出效果。比如:

1.gif

因为我们这里定义的填充色是透明的所有只有边框色,让了如果你需要Button有点击反应的同时还能有圆角的样式,也是可以通过Shape来实现的,只需要修改填充色(solid)和对应的state即可。效果如下:

2.gif

当然我们也可以在原有的基础上给边框加上对应状态下不同的颜色

3.gif

  • 对于Selector的注意点

这里我要说的注意点只有一点,就是前面所提到的Selector的最后一个item一定要加上一个没有写state的item,这个item就是默认状态下的item。不过对于这里的默认,大多数人存在误区,很多人可能认为对于state_pressed默认状态就是false,state_selected默认状态也是false,我们只需要写一个state_pressed=true或者state_selected=true的item再写一个默认状态下的item即可。

我要告诉大家的是:尔等错了~~

至于为什么错了,我们就以一个按钮(默认:浅蓝色,按下去:深蓝色)为例。 
按照大部分人以往的认知,应该是这么写

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_blue_dark" android:state_pressed="true"/>
    <item android:drawable="@android:color/holo_blue_light"/>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

没有任何问题,效果也如我们预期的一样(大家都知道的,图就不贴了)。 
那么,为什么我会说大家错了呢?如果我们将上面的代码片段改成下面这样呢:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_blue_dark"  android:state_pressed="false"/>
    <item android:drawable="@android:color/holo_blue_light"/>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

我们只是把第一个item的state_pressed由true改为了false。如果找大家之前的想法“最后一个默认的item对于state_pressed值为false”,那么照理来讲那么对于这个按钮默认状态下(没有按下去)是深蓝色(selector对于重复state只会取第一个有效值,后面的无效,大家可以自己验证),按下去我们是没有设置的(照理来讲应该是透明的,或者系统默认的button背景色,大部分手机是深灰色)。我们来看一下效果是什么样的: 
4.gif

我们发现:没有按下去的时候确实是深蓝色,按下去之后却成了浅蓝色。

这是不是就印证了我所说的“尔等错了”(容我嘚瑟一下,哈哈~)

正解应该是最后一个默认item的state包含前面所有item的state值的相反值。意思就是前面有个state_pressed=true的最后一个item就默认加上了一个state_pressed=false,前面有个state_focused=false的最后一个item就默认加上了一个state_focused=true的item。(我已经多次验证过了,如果谁有更好的理解,欢迎指出!)

  • 默认item出现的位置

我们先来把之前的代码修改一下:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_orange_dark" android:state_selected="true"/>
    <item android:drawable="@android:color/holo_blue_dark" android:state_pressed="true"/>
    <item android:drawable="@android:color/holo_blue_light"/>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在给按钮加个监听:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        button.setSelected(!button2.isSelected());
    }
});
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

效果是这样的: 
5.gif

没有任何问题,但是如果我们将selector的默认item放到最前面:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_blue_light"/>
    <item android:drawable="@android:color/holo_orange_dark" android:state_selected="true"/>
    <item android:drawable="@android:color/holo_blue_dark" android:state_pressed="true"/>
</selector>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

效果就变成了这样: 
6.gif

我们发现不论是默认状态、点击状态、还是选中状态全都是一样的,显示的都是默认item。

这里就要注意另一个很重要的一点了:范围大的item必须写在范围小的item的后面,默认item必须写在selector的最后一行。其实根据这一点,我们又会发现我们前面对于默认item的state的总结是有误的,如果默认item只是有与其他item的state相反的state那么,当把它放在前面的时候应该是不会影响其他的item的,可想而知默认item应该是对于每个state不论true还是false都存在,因为selector对于重复的state只取第一个有效,这也就解释了为什么把默认item放在最前面,后面的item不起作用了。

  • Selector代码实现

    • 废话了那么多,终于到了重点了。在Android SDK中Selector对应的Java类是android.graphics.drawable.StateListDrawable,对于Selector下的每一个item我们使用addState的方式来添加,比如我们想要添加一个state_pressed=true时背景色为蓝色的item,我们可以采用这段代码

      StateListDrawable selector = new StateListDrawable();
      selector.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(Color.BLACK));
           
           
      • 1
      • 2
      • 1
      • 2

      如果想要添加一个state_enabled=false的item,我们可以这样:

      selector.addState(new int[]{-android.R.attr.state_enabled}, new ColorDrawable(Color.GRAY));
           
           
      • 1
      • 1

      之后再给对应的view setBackground即可。 
      需要注意的是默认item的state我们写:new int[]{}

    • 对于Shape对应的Java类是android.graphics.drawable.GradientDrawable,如果想要实现一个我一开始给大家展示的EditText的那种边框,我们可以采用以下这段代码:

      StateListDrawable selector = new StateListDrawable();
      
      GradientDrawable focusedShape = getItemShape(GradientDrawable.RECTANGLE,
          20, Color.TRANSPARENT, 1, Color.RED);
      selector.addState(new int[]{android.R.attr.state_focused}, focusedShape);
      
      GradientDrawable defaultShape = getItemShape(GradientDrawable.RECTANGLE,
              20, Color.TRANSPARENT, 1, Color.GRAY);
      selector.addState(new int[]{android.R.attr.state_focused}, defaultShape);
      
      private GradientDrawable getItemShape(int shape, int cornerRadius,
              int solidColor, int strokeWidth, int strokeColor) {
          GradientDrawable drawable = new GradientDrawable();
          drawable.setShape(shape);
          drawable.setStroke(strokeWidth, strokeColor);
          drawable.setCornerRadius(cornerRadius);
          drawable.setColor(solidColor);
          return drawable;
      }
           
           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 知道了Selector与Shape对应的Java类,以及item的规则(前面废话了那么多,就是为了现在服务)之后,开始完成我们的工具类(我们就以Selector套Shape为例,其他的关于文字颜色,以及使用图片作为背景会在后文源码中公布):平时我们用到的Selector无非就是enabled,pressed,selected,focused和默认这几种状态。对于Shape而言,还有个形状。好的,我们就定义一个类ShapeSelector

      public static final class ShapeSelector {
      
          @IntDef({GradientDrawable.RECTANGLE, GradientDrawable.OVAL,
                  GradientDrawable.LINE, GradientDrawable.RING})
          private @interface Shape {}
      
          private int mShape;               //the shape of background
          private int mDefaultBgColor;      //default background color
          private int mDisabledBgColor;     //state_enabled = false
          private int mPressedBgColor;      //state_pressed = true
          private int mSelectedBgColor;     //state_selected = true
          private int mFocusedBgColor;      //state_focused = true
          private int mStrokeWidth;         //stroke width in pixel
          private int mDefaultStrokeColor;  //default stroke color
          private int mDisabledStrokeColor; //state_enabled = false
          private int mPressedStrokeColor;  //state_pressed = true
          private int mSelectedStrokeColor; //state_selected = true
          private int mFocusedStrokeColor;  //state_focused = true
          private int mCornerRadius;        //corner radius
      
          private boolean hasSetDisabledBgColor = false;
          private boolean hasSetPressedBgColor = false;
          private boolean hasSetSelectedBgColor = false;
          private boolean hasSetFocusedBgColor = false;
      
          private boolean hasSetDisabledStrokeColor = false;
          private boolean hasSetPressedStrokeColor = false;
          private boolean hasSetSelectedStrokeColor = false;
          private boolean hasSetFocusedStrokeColor = false;
      
          public ShapeSelector() {
              //initialize default values
              mShape = GradientDrawable.RECTANGLE;
              mDefaultBgColor = Color.TRANSPARENT;
              mDisabledBgColor = Color.TRANSPARENT;
              mPressedBgColor = Color.TRANSPARENT;
              mSelectedBgColor = Color.TRANSPARENT;
              mFocusedBgColor = Color.TRANSPARENT;
              mStrokeWidth = 0;
              mDefaultStrokeColor = Color.TRANSPARENT;
              mDisabledStrokeColor = Color.TRANSPARENT;
              mPressedStrokeColor = Color.TRANSPARENT;
              mSelectedStrokeColor = Color.TRANSPARENT;
              mFocusedStrokeColor = Color.TRANSPARENT;
              mCornerRadius = 0;
          }
      
          public ShapeSelector setShape(@Shape int shape) {
              mShape = shape;
              return this;
          }
      
          public ShapeSelector setDefaultBgColor(@ColorInt int color) {
              mDefaultBgColor = color;
              if (!hasSetDisabledBgColor)
                  mDisabledBgColor = color;
              if (!hasSetPressedBgColor)
                  mPressedBgColor = color;
              if (!hasSetSelectedBgColor)
                  mSelectedBgColor = color;
              if (!hasSetFocusedBgColor)
                  mFocusedBgColor = color;
              return this;
          }
      
          public ShapeSelector setDisabledBgColor(@ColorInt int color) {
              mDisabledBgColor = color;
              hasSetDisabledBgColor = true;
              return this;
          }
      
          public ShapeSelector setPressedBgColor(@ColorInt int color) {
              mPressedBgColor = color;
              hasSetPressedBgColor = true;
              return this;
          }
      
          public ShapeSelector setSelectedBgColor(@ColorInt int color) {
              mSelectedBgColor = color;
              hasSetSelectedBgColor = true;
              return this;
          }
      
          public ShapeSelector setFocusedBgColor(@ColorInt int color) {
              mFocusedBgColor = color;
              hasSetPressedBgColor = true;
              return this;
          }
      
          public ShapeSelector setStrokeWidth(@Dimension int width) {
              mStrokeWidth = width;
              return this;
          }
      
          public ShapeSelector setDefaultStrokeColor(@ColorInt int color) {
              mDefaultStrokeColor = color;
              if (!hasSetDisabledStrokeColor)
                  mDisabledStrokeColor = color;
              if (!hasSetPressedStrokeColor)
                  mPressedStrokeColor = color;
              if (!hasSetSelectedStrokeColor)
                  mSelectedStrokeColor = color;
              if (!hasSetFocusedStrokeColor)
                  mFocusedStrokeColor = color;
              return this;
          }
      
          public ShapeSelector setDisabledStrokeColor(@ColorInt int color) {
              mDisabledStrokeColor = color;
              hasSetDisabledStrokeColor = true;
              return this;
          }
      
          public ShapeSelector setPressedStrokeColor(@ColorInt int color) {
              mPressedStrokeColor = color;
              hasSetPressedStrokeColor = true;
              return this;
          }
      
          public ShapeSelector setSelectedStrokeColor(@ColorInt int color) {
              mSelectedStrokeColor = color;
              hasSetSelectedStrokeColor = true;
              return this;
          }
      
          public ShapeSelector setFocusedStrokeColor(@ColorInt int color) {
              mFocusedStrokeColor = color;
              hasSetFocusedStrokeColor = true;
              return this;
          }
      
          public ShapeSelector setCornerRadius(@Dimension int radius) {
              mCornerRadius = radius;
              return this;
          }
      
          public StateListDrawable create() {
              StateListDrawable selector = new StateListDrawable();
      
              //enabled = false
              if (hasSetDisabledBgColor || hasSetDisabledStrokeColor) {
                  GradientDrawable disabledShape = getItemShape(mShape, mCornerRadius,
                          mDisabledBgColor, mStrokeWidth, mDisabledStrokeColor);
                  selector.addState(new int[]{-android.R.attr.state_enabled}, disabledShape);
              }
      
              //pressed = true
              if (hasSetPressedBgColor || hasSetPressedStrokeColor) {
                  GradientDrawable pressedShape = getItemShape(mShape, mCornerRadius,
                          mPressedBgColor, mStrokeWidth, mPressedStrokeColor);
                  selector.addState(new int[]{android.R.attr.state_pressed}, pressedShape);
              }
      
              //selected = true
              if (hasSetSelectedBgColor || hasSetSelectedStrokeColor) {
                  GradientDrawable selectedShape = getItemShape(mShape, mCornerRadius,
                          mSelectedBgColor, mStrokeWidth, mSelectedStrokeColor);
                  selector.addState(new int[]{android.R.attr.state_selected}, selectedShape);
              }
      
              //focused = true
              if (hasSetFocusedBgColor || hasSetFocusedStrokeColor) {
                  GradientDrawable focusedShape = getItemShape(mShape, mCornerRadius,
                          mFocusedBgColor, mStrokeWidth, mFocusedStrokeColor);
                  selector.addState(new int[]{android.R.attr.state_focused}, focusedShape);
              }
      
              //default
              GradientDrawable defaultShape = getItemShape(mShape, mCornerRadius,
                      mDefaultBgColor, mStrokeWidth, mDefaultStrokeColor);
              selector.addState(new int[]{}, defaultShape);
      
              return selector;
          }
      
          private GradientDrawable getItemShape(int shape, int cornerRadius,
                  int solidColor, int strokeWidth, int strokeColor) {
              GradientDrawable drawable = new GradientDrawable();
              drawable.setShape(shape);
              drawable.setStroke(strokeWidth, strokeColor);
              drawable.setCornerRadius(cornerRadius);
              drawable.setColor(solidColor);
              return drawable;
          }
      }
           
           
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137
      • 138
      • 139
      • 140
      • 141
      • 142
      • 143
      • 144
      • 145
      • 146
      • 147
      • 148
      • 149
      • 150
      • 151
      • 152
      • 153
      • 154
      • 155
      • 156
      • 157
      • 158
      • 159
      • 160
      • 161
      • 162
      • 163
      • 164
      • 165
      • 166
      • 167
      • 168
      • 169
      • 170
      • 171
      • 172
      • 173
      • 174
      • 175
      • 176
      • 177
      • 178
      • 179
      • 180
      • 181
      • 182
      • 183
      • 184
      • 185
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137
      • 138
      • 139
      • 140
      • 141
      • 142
      • 143
      • 144
      • 145
      • 146
      • 147
      • 148
      • 149
      • 150
      • 151
      • 152
      • 153
      • 154
      • 155
      • 156
      • 157
      • 158
      • 159
      • 160
      • 161
      • 162
      • 163
      • 164
      • 165
      • 166
      • 167
      • 168
      • 169
      • 170
      • 171
      • 172
      • 173
      • 174
      • 175
      • 176
      • 177
      • 178
      • 179
      • 180
      • 181
      • 182
      • 183
      • 184
      • 185

      我们采用Builder模式方便对ShapeSelector设置各种状态下的属性,最后调用create方法直接生成StateListDrawable对象设置给对应的View即可。

  • 接下来我们来看一下效果

    et1.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultStrokeColor(Color.GRAY)
            .setFocusedStrokeColor(Color.YELLOW)
            .setStrokeWidth(2)
            .create());
    et2.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultStrokeColor(Color.GRAY)
            .setFocusedStrokeColor(Color.YELLOW)
            .setStrokeWidth(2)
            .setCornerRadius(20)
            .create());
    et3.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultStrokeColor(Color.GRAY)
            .setFocusedStrokeColor(Color.RED)
            .setStrokeWidth(2)
            .create());

    et1.setHintTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.GRAY)
            .setFocusedColor(Color.BLACK)
            .create());
    et2.setHintTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.GRAY)
            .setFocusedColor(Color.BLACK)
            .create());
    et3.setHintTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.GRAY)
            .setFocusedColor(Color.BLACK)
            .create());

    et1.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setFocusedColor(Color.YELLOW)
            .create());
    et2.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setFocusedColor(Color.YELLOW)
            .create());
    et3.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setFocusedColor(Color.RED)
            .create());
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

7.gif

    btn1.setBackground(SelectorFactory.newGeneralSelector()
            .setDefaultDrawable(ContextCompat.getDrawable(this, R.mipmap.blue_primary))
            .setPressedDrawable(this, R.mipmap.blue_primary_dark)
            .create());
    btn2.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_light))
            .setPressedBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_dark))
            .create());
    btn3.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_light))
            .setPressedBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_dark))
            .setSelectedBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_dark))
            .setCornerRadius(20)
            .create());
    btn3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            btn3.setSelected(!btn3.isSelected());
        }
    });
    btn4.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_light))
            .setPressedBgColor(ContextCompat.getColor(this, android.R.color.holo_blue_dark))
            .setDisabledBgColor(Color.GRAY)
            .create());
    btn4.setEnabled(false);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

8.gif

    tv1.setBackground(SelectorFactory.newShapeSelector()
            .setDefaultStrokeColor(Color.GRAY)
            .setStrokeWidth(1)
            .setCornerRadius(20)
            .create());
    tv2.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setPressedColor(Color.YELLOW)
            .create());
    tv3.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setSelectedColor(Color.YELLOW)
            .create());
    tv3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            tv3.setSelected(!tv3.isSelected());
        }
    });
    tv4.setTextColor(SelectorFactory.newColorSelector()
            .setDefaultColor(Color.BLACK)
            .setSelectedColor(Color.YELLOW)
            .setDisabledColor(Color.GRAY)
            .create());
    tv4.setEnabled(false);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

9.gif

  • 使用捷径 
    有人可能会说:虽然是可以不用再定义很多的xml文件了,但是一个页面有很多的view,我不是要对每个view都是挨个设置一下背景嘛,这岂不更麻烦。 
    ——简单,我们自定义一个View继承一下原有的View,再自定义一些属性,然后在构造方法里面拿到这些属性,用我们的工具类给他设置上不就行了嘛,这样是需要再写布局的时候写一下属性就行了。

  • Github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值