圆角矩形背景,可变色,可左右方向渐变背景色,TextView
项目中常常用到圆角矩形按钮,空心的、实心的、纯圆角的、任意radius的、背景颜色各种的、甚至颜色渐变的
过去drawable中存在大量xml文件用来设置shape,这个自定义控件就是为了解决这个问题,避免在drawable中创建大量的shape/selector文件
public class ColorTagView extends AppCompatTextView {
public static final int TAG_FILL_TYPE = 1;//背景填充满
public static final int TAG_STROKE_TYPE = 2;//背景空心带边缘
public static final int TAG_NOBG_TYPE = 3;//无背景
private GradientDrawable mDrawable;
private GradientDrawable mMaskDrawable;
private static final String DEFAULT_STROKE_COLOR = "#ff8c99";//默认背景边缘线颜色
private static final String DEFAULT_BACKGROUND_COLOR = "#00000000";
private static final String DEFAULT_MASK_COLOR = "#26000000";//遮罩颜色,默认是20%黑色
private static final int DEFAULT_STROKE_WIDTH = 1;
private static final int HORIZONTAL_PADDING = 6;//dp 默认左右边padding
private static final int VERTICAL_PADDING = 3;//dp 默认上下边padding
private int mStrokeWidth;
private float mRadius;//dp 默认圆角半径
private boolean isRoundRect;//是否圆角
private int mHozPadding;
private int mVertPadding;
private int mStrokeColor;
/**按压颜色*/
private int mPressedColor;
private boolean mGradientType;
private int mStartTagColor;
private int mEndTagColor;
private int mTagType;
public ColorTagView1(Context context) {
this(context, null);
}
public ColorTagView1(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorTagView1(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorTagView);
mRadius = a.getDimension(R.styleable.ColorTagView_radius, 0);
isRoundRect = a.getBoolean(R.styleable.ColorTagView_isRoundRect, false);
mGradientType = a.getBoolean(R.styleable.ColorTagView_gradientType, false);
mStrokeColor = a.getColor(R.styleable.ColorTagView_tagColor, Color.parseColor(DEFAULT_STROKE_COLOR));
mStartTagColor = a.getColor(R.styleable.ColorTagView_startTagColor, Color.parseColor(DEFAULT_STROKE_COLOR));
mEndTagColor = a.getColor(R.styleable.ColorTagView_endTagColor, Color.parseColor(DEFAULT_STROKE_COLOR));
mStrokeWidth = a.getDimensionPixelSize(R.styleable.ColorTagView_strokeWidth, DEFAULT_STROKE_WIDTH);
mTagType = a.getInt(R.styleable.ColorTagView_tagType, TAG_NOBG_TYPE);
mHozPadding = a.getDimensionPixelSize(R.styleable.ColorTagView_horizontalPadding, HORIZONTAL_PADDING);
mVertPadding = a.getDimensionPixelSize(R.styleable.ColorTagView_verticalPadding, VERTICAL_PADDING);
mPressedColor=a.getColor(R.styleable.ColorTagView_pressedColor,Color.parseColor(DEFAULT_MASK_COLOR));
a.recycle();
setPadding(mHozPadding, mVertPadding, mHozPadding, mVertPadding);
setGravity(Gravity.CENTER);
setColor(mStrokeColor);
}
private GradientDrawable getDrawable() {
if (mDrawable == null) {
mDrawable = new GradientDrawable();
switch (mTagType) {
case TAG_STROKE_TYPE:
mDrawable.setStroke(mStrokeWidth, mStrokeColor);
mDrawable.setColor(Color.parseColor(DEFAULT_BACKGROUND_COLOR));
break;
case TAG_FILL_TYPE:
mDrawable.setStroke(mStrokeWidth, mStrokeColor);
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
if (mGradientType && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mDrawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
mDrawable.setColors(new int[]{mStartTagColor, mEndTagColor});
} else {
mDrawable.setColor(mStrokeColor);
}
break;
case TAG_NOBG_TYPE:
mDrawable.setColor(Color.parseColor(DEFAULT_BACKGROUND_COLOR));
break;
}
mDrawable.setCornerRadius(mRadius);
}
return mDrawable;
}
private Drawable getMaskDrawable() {
if (mMaskDrawable == null) {
mMaskDrawable = new GradientDrawable();
mMaskDrawable.setColor(mPressedColor);
mMaskDrawable.setStroke(mStrokeWidth, mStrokeColor);
mMaskDrawable.setCornerRadius(mRadius);
}
return mMaskDrawable;
}
private Drawable getStateDrawable() {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable normalDrawable = getDrawable();
Drawable pressedDrawable = getMaskDrawable();
if (pressedDrawable != null) {
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, pressedDrawable);
stateListDrawable.addState(new int[]{android.R.attr.state_focused}, pressedDrawable);
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);
stateListDrawable.addState(new int[]{android.R.attr.state_checked}, pressedDrawable);
}
if (normalDrawable != null) {
stateListDrawable.addState(new int[]{}, normalDrawable);
}
return stateListDrawable;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (isRoundRect) {
mRadius = getMeasuredHeight() / 2f;
setColor(mStrokeColor);
}
}
/**
* 设置文字及背景颜色
*/
public void setColor(String color) {
switch (mTagType) {
case TAG_STROKE_TYPE:
// setTextColor(Color.parseColor(color));
break;
case TAG_FILL_TYPE:
getDrawable().setColor(Color.parseColor(color));
setTextColor(getContext().getResources().getColor(android.R.color.white));
break;
case TAG_NOBG_TYPE:
// setTextColor(Color.parseColor(color));
break;
}
getDrawable().setStroke(mStrokeWidth, Color.parseColor(color));
setMyBackground();
}
/**
* 设置文字及背景颜色
*/
public void setColor(int color) {
switch (mTagType) {
case TAG_STROKE_TYPE:
// setTextColor(color);
break;
case TAG_FILL_TYPE:
getDrawable().setColor(color);
setTextColor(getContext().getResources().getColor(android.R.color.white));
break;
case TAG_NOBG_TYPE:
// setTextColor(color);
break;
}
getDrawable().setStroke(mStrokeWidth, color);
setMyBackground();
}
private void setMyBackground() {
Drawable drawable = getStateDrawable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(drawable);
} else {
setBackgroundDrawable(drawable);
}
}
}
自定义属性
<declare-styleable name="ColorTagView">
<attr name="strokeWidth" format="dimension"/><!--边框粗细-->
<attr name="radius" format="dimension"/><!--圆角大小-->
<attr name="isRoundRect" format="boolean"/><!--是否纯圆角-->
<attr name="tagColor" format="color"/><!--颜色-->
<attr name="startTagColor" format="color"/><!--渐变背景起始颜色-->
<attr name="endTagColor" format="color"/><!--渐变背景结束颜色-->
<attr name="gradientType" format="boolean"/><!--是否渐变-->
<attr name="horizontalPadding" format="dimension"/><!--横向padding-->
<attr name="verticalPadding" format="dimension"/><!--纵向padding-->
<attr name="tagType">
<enum name="fill" value="1"/> <!--背景填充-->
<enum name="stroke" value="2"/><!--背景边框-->
<enum name="normal" value="3"/><!--无背景-->
</attr>
<attr name="pressedColor" format="color"/>
</declare-styleable>
使用方式
<xxx.ColorTagView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
app:strokeWidth="1dp"
app:tagColor="#ff5900"
app:pressedColor="#ffeee6"
app:radius="20dp"
app:isRoundRect="true"
android:textColor="#ff5900"
android:lines="1"
app:horizontalPadding="13dp"
app:verticalPadding="9dp"
android:textSize="13sp"
android:text="按钮文字"/>
效果: