自定义控件的时候我们往往需要写很多shape文件,非常复杂繁琐,对shape的命名就非常头痛.那么有没有一种方式可以纯代码实现呢?下面我们就用StateListDrawable来进行实现.需要配合GradientDrawable来实现.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.tv);
tv.setBackground(defineMyBG());
}
private Drawable defineMyBG() {
StateListDrawable sd = new StateListDrawable();
//注意该处的顺序,只要有一个状态与之相配,背景就会被换掉
//所以不要把大范围放在前面了,如果sd.addState(new[]{},normal)放在第一个的话,就没有什么效果了
sd.addState(new int[]{android.R.attr.state_selected}, getStateDrawable(State.SELECTED));
sd.addState(new int[]{android.R.attr.state_focused}, getStateDrawable(State.FOCUSED));
sd.addState(new int[]{android.R.attr.state_pressed}, getStateDrawable(State.PRESSED));
//必选添加在最后一个状态
sd.addState(new int[]{}, getStateDrawable(State.NORMAL));
return sd;
}
private Drawable getStateDrawable(State state) {
GradientDrawable shape = new GradientDrawable();
//设置形状
shape.setShape(GradientDrawable.RECTANGLE);//设置形状圆角矩形,椭圆;
shape.setCornerRadius(20);//设置圆角大小
switch (state) {
case ENABLED://tip: 不能写成State.ENABLED 至于为什么我也不懂.
shape.setColor(Color.RED);
break;
case FOCUSED:
shape.setColor(Color.GREEN);
break;
case PRESSED:
shape.setColor(Color.YELLOW);
break;
case NORMAL:
shape.setColor(Color.BLUE);
break;
}
//参数含义: 边线宽度;边线颜色;虚线长度dashWidth;虚线空格长度dashGap
shape.setStroke(2, Color.BLACK, 5, 3);
return shape;
}
/**
* 用枚举实现,减少传参的错误
*/
public enum State {
SELECTED, PRESSED, FOCUSED, ENABLED, NORMAL
}
}
下面是实现的效果:
GIF.gif题外话:本文只是抛砖引玉大家自己封装成工具类,调用起来自己舒服即可!
而且GradientDrawable还有很多功能,比如设置渐变色,设置shader,完全可以用动态改变,自由度很高.
网友评论