您的位置:首页 > Web前端 > CSS

搞定字体样式、背景的工具类(shape、selector、drawable)

2017-12-16 19:47 363 查看

一、封装背景

平时开发过程中,你可能遇到项目中res\drawable文件夹中selector、layer-list这种文件很多,而且这些文件都是大同小异,可能只是一个color或者width不一样而已。随着项目的需求更改、业务逻辑的复杂,这些文件也会变得越多和不可控制。还有长远的考虑,后期维护代码也难去修改和删除。能否有一个工具类不用再写selector、layer-list文件,只需要用到的地方进行代码设置即可。答案是有的。

说了这么多,先看一下封装后运行起来的界面。



github地址:https://github.com/hjy15759633702/CustomView.git

二、封装后使用

1、如何使用

直接在xml配置:

<com.hjy.customlibrary.view.CustomTextView
android:id="@+id/setShapeAndTextByXml"
android:layout_width="100dp"
android:layout_height="100dp"
android:gravity="center"
android:textColor="@color/colorBlack"
android:text="xml设置shape、textColor"
android:layout_marginTop="10dp"
custom:DefaultBgColor="@color/colorWhite"
custom:SelectedBgColor="@color/colorRed"
custom:PressedBgColor="@color/colorGray"
custom:FocusedBgColor="@color/colorWhite"
custom:DisabledBgColor="@color/colorGray"
custom:DefaultStrokeColor="@color/colorGray"
custom:SelectedStrokeColor="@color/colorBlack"
custom:PressedStrokeColor="@color/colorRed"
custom:FocusedStrokeColor="@color/colorYellow"
custom:DisabledStrokeColor="@color/colorBlack"
custom:DefaultColor="@color/colorBlack"
custom:PressedColor="@color/colorRed"
custom:SelectedColor="@color/colorWhite"
custom:DisabledColor="@color/colorBlack"
custom:FocusedColor="@color/colorYellow"
custom:strokeWidth="1px"
custom:ShowLeftStroke="false"
custom:ShowRightStroke="false"
custom:TopStrokeWidth="10px"
custom:TRRadius="50px"
custom:BLRadius="50px" />


代码设置字体setTextColor和设置背景setBackground:

setShapeAndTextByCode_1.setBackground(
Selector.shapeBuild()
.setDefaultStrokeColor
1d82f
(Color.GRAY)
.setSelectedStrokeColor(Color.BLACK)
.setPressedStrokeColor(Color.RED)
.setDisabledStrokeColor(Color.BLACK)
.setFocusedStrokeColor(Color.YELLOW)
.setDefaultBgColor(Color.WHITE)
.setSelectedBgColor(Color.RED)
.setPressedBgColor(Color.GRAY)
.setFocusedBgColor(Color.WHITE)
.setDisabledBgColor(Color.GRAY)
.setStrokeWidth(2)
.setTRRadius(50)
.setBLRadius(50)
.setTopStrokeWidth(10)
.setShowLeftStroke(false)
.setShowRightStroke(false)
.create());
setShapeAndTextByCode_1.setTextColor(Selector.colorBuild()
.setDefaultColor(Color.BLACK)
.setPressedColor(Color.RED)
.setSelectedColor(Color.WHITE)
.setDisabledColor(Color.BLACK)
.setFocusedColor(Color.YELLOW)
.create());


2、封装思路

为了更加快速全面理清字体颜色、背景样式的属性,画了思维导图。



看上图,一目了然,我们需要用到的样式以及需要设置属性。

3、封装工具类Selector

自定义一个Selector工具类,工具类含有形状ShapeSelector、ColorSelector、DrawableSelector静态类。

ShapeSelector:主要包含形状shape、圆角半径、边框大小、五种状态(默认、选中、不可用、点击、获取焦点)背景颜色和边框颜色、上下左右边框大小以及显示情况等。

ColorSelector:主要包含五种状态(默认、选中、不可用、点击、获取焦点)字体颜色。

DrawableSelector:主要包含五种状态(默认、选中、不可用、点击、获取焦点)设置背景调用的Drawable资源。

代码如下:

/**
* Selector
* @author hjy
* created at 2017/12/11 22:35
*/
public class Selector {

public static ShapeSelector shapeBuild() {
return new ShapeSelector();
}

public static ColorSelector colorBuild() {
return new ColorSelector();
}

public static DrawableSelector drawableBuild() {
return new DrawableSelector();
}

/**
* 形状ShapeSelector
* @author hjy
* created at 2017/12/11 22:26
*/
public static final class ShapeSelector {

// 只支持长方形、圆形
@IntDef({GradientDrawable.RECTANGLE})
private @interface Shape {}

private int mShape;               //the shape of background
private int mCornerRadius;        //corner radius

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 mTLRadius;
private int mTRRadius;
private int mBLRadius;
private int mBRRadius;

// 上边框显示,前提边框的宽度不为0
private boolean mShowTopStroke = true;
// 下边框显示,前提边框的宽度不为0
private boolean mShowBottomStroke = true;
// 左边框显示,前提边框的宽度不为0
private boolean mShowLeftStroke = true;
// 右边框显示,前提边框的宽度不为0
private boolean mShowRightStroke = true;

// 上边框宽度
private int mTopStrokeWidth;
// 下边框宽度
private int mBottomStrokeWidth;
// 左边框宽度
private int mLeftStrokeWidth;
// 右边框宽度
private int mRightStrokeWidth;

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;

private ShapeSelector() {
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;
mTLRadius = mCornerRadius;
mTRRadius = mCornerRadius;
mBLRadius = mCornerRadius;
mBRRadius = mCornerRadius;
// 刚开始四个边框都要显示
mShowTopStroke = true;
mShowBottomStroke = true;
mShowLeftStroke = true;
mShowRightStroke = true;
// 刚开始四个边框大小
// 上边框宽度
mTopStrokeWidth = mStrokeWidth;
// 下边框宽度
mBottomStrokeWidth = mStrokeWidth;
// 左边框宽度
mLeftStrokeWidth = mStrokeWidth;
// 右边框宽度
mRightStrokeWidth = mStrokeWidth;
}

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 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 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;
hasSetFocusedBgColor = true;
return this;
}

public ShapeSelector setStrokeWidth(@Dimension int width) {
mStrokeWidth = width;
mTopStrokeWidth = mStrokeWidth;
mBottomStrokeWidth = mStrokeWidth;
mLeftStrokeWidth = mStrokeWidth;
mRightStrokeWidth = mStrokeWidth;
mShowTopStroke = true;
mShowBottomStroke = true;
mShowLeftStroke = true;
mShowRightStroke = true;
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;
mTLRadius = mCornerRadius;
mTRRadius = mCornerRadius;
mBLRadius = mCornerRadius;
mBRRadius = mCornerRadius;
return this;
}

public ShapeSelector setTLRadius(@Dimension int tLRadius) {
mTLRadius = tLRadius;
return this;
}

public ShapeSelector setTRRadius(@Dimension int tRadius) {
mTRRadius = tRadius;
return this;
}

public ShapeSelector setBLRadius(@Dimension int bLRadius) {
mBLRadius = bLRadius;
return this;
}

public ShapeSelector setBRRadius(@Dimension int bRRadius) {
mBRRadius = bRRadius;
return this;
}

public ShapeSelector setShowTopStroke(boolean showTopStroke) {
this.mShowTopStroke = showTopStroke;
if (!mShowTopStroke)
mTopStrokeWidth = 0;
return this;
}

public ShapeSelector setShowBottomStroke(boolean showBottomStroke) {
this.mShowBottomStroke = showBottomStroke;
if (!mShowBottomStroke)
mBottomStrokeWidth = 0;
return this;
}

public ShapeSelector setShowLeftStroke(boolean showLeftStroke) {
this.mShowLeftStroke = showLeftStroke;
if (!mShowLeftStroke)
//                if (mLeftStrokeWidth != 0)
//                    throw new RuntimeException("showLeftStroke is false, the leftStrokeWidth is 0");
mLeftStrokeWidth = 0;
return this;
}

public ShapeSelector setShowRightStroke(boolean showRightStroke) {
this.mShowRightStroke = showRightStroke;
if (!mShowRightStroke)
mRightStrokeWidth = 0;
return this;
}

public ShapeSelector setTopStrokeWidth(int topStrokeWidth) {
this.mTopStrokeWidth = topStrokeWidth;
if (!mShowTopStroke)
mTopStrokeWidth = 0;
return this;
}

public ShapeSelector setBottomStrokeWidth(int bottomStrokeWidth) {
this.mBottomStrokeWidth = bottomStrokeWidth;
if (!mShowBottomStroke)
mBottomStrokeWidth = 0;
return this;
}

public ShapeSelector setLeftStrokeWidth(int leftStrokeWidth) {
this.mLeftStrokeWidth = leftStrokeWidth;
if (!mShowLeftStroke)
mLeftStrokeWidth = 0;
return this;
}

public ShapeSelector setRightStrokeWidth(int rightStrokeWidth) {
this.mRightStrokeWidth = rightStrokeWidth;
if (!mShowRightStroke)
mRightStrokeWidth = 0;
return this;
}

public StateListDrawable create() {
StateListDrawable selector = new StateListDrawable();
// 左上,右上,右下,左下
float[] radii = new float[]{mTLRadius,mTLRadius,mTRRadius,mTRRadius,mBRRadius,mBRRadius,mBLRadius,mBLRadius};
// 上,下,左,右 宽大小
int[] showStrokeWidth = new int[]{mTopStrokeWidth,mBottomStrokeWidth,mLeftStrokeWidth,mRightStrokeWidth};

//enabled = true
if (hasSetDisabledBgColor || hasSetDisabledStrokeColor) {
Drawable disabledShape = getShape(mShape, mDisabledBgColor, mDisabledStrokeColor, showStrokeWidth, radii);
selector.addState(new int[]{-android.R.attr.state_enabled}, disabledShape);
}

//pressed = true
if (hasSetPressedBgColor || hasSetPressedStrokeColor) {
Drawable pressedShape = getShape(mShape, mPressedBgColor, mPressedStrokeColor, showStrokeWidth, radii);
selector.addState(new int[]{android.R.attr.state_pressed}, pressedShape);
}

//selected = true
if (hasSetSelectedBgColor || hasSetSelectedStrokeColor) {
Drawable selectedShape = getShape(mShape, mSelectedBgColor, mSelectedStrokeColor, showStrokeWidth, radii);
selector.addState(new int[]{android.R.attr.state_selected}, selectedShape);
}

//focused = true
if (hasSetFocusedBgColor || hasSetFocusedStrokeColor) {
Drawable focusedShape = getShape(mShape, mFocusedBgColor, mFocusedStrokeColor, showStrokeWidth, radii);
selector.addState(new int[]{android.R.attr.state_focused}, focusedShape);
}

//default
Drawable defaultShape = getShape(mShape, mDefaultBgColor, mDefaultStrokeColor, showStrokeWidth, radii);
selector.addState(new int[]{}, defaultShape);

return selector;
}

private Drawable getShape(int shape, int solidColor, int strokeColor, int[] showStrokeWidth, float[] radii) {
GradientDrawable befor_drawable = getDrawable(shape, strokeColor, radii);
GradientDrawable after_drawable = getDrawable(shape, solidColor, radii);
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{befor_drawable,after_drawable});
layerDrawable.setLayerInset(1,showStrokeWidth[2],showStrokeWidth[0],showStrokeWidth[3],showStrokeWidth[1]);
return layerDrawable;
}

private GradientDrawable getDrawable(int shape, int solidColor, float[] radii) {
GradientDrawable drawable = new GradientDrawable();
drawable.setShape(shape);
drawable.setCornerRadii(radii);
drawable.setColor(solidColor);
return drawable;
}
}

/**
* 资源DrawableSelector
* @author hjy
* created at 2017/12/11 22:34
*/
public static final class DrawableSelector {

private Drawable mDefaultDrawable;
private Drawable mDisabledDrawable;
private Drawable mPressedDrawable;
private Drawable mSelectedDrawable;
private Drawable mFocusedDrawable;

private boolean hasSetDisabledDrawable = false;
private boolean hasSetPressedDrawable = false;
private boolean hasSetSelectedDrawable = false;
private boolean hasSetFocusedDrawable = false;

private DrawableSelector() {
mDefaultDrawable = new ColorDrawable(Color.TRANSPARENT);
}

public DrawableSelector setDefaultDrawable(Drawable drawable) {
mDefaultDrawable = drawable;
if (!hasSetDisabledDrawable)
mDisabledDrawable = drawable;
if (!hasSetPressedDrawable)
mPressedDrawable = drawable;
if (!hasSetSelectedDrawable)
mSelectedDrawable = drawable;
if (!hasSetFocusedDrawable)
mFocusedDrawable = drawable;
return this;
}

public DrawableSelector setDisabledDrawable(Drawable drawable) {
mDisabledDrawable = drawable;
hasSetDisabledDrawable = true;
return this;
}

public DrawableSelector setPressedDrawable(Drawable drawable) {
mPressedDrawable = drawable;
hasSetPressedDrawable = true;
return this;
}

public DrawableSelector setSelectedDrawable(Drawable drawable) {
mSelectedDrawable = drawable;
hasSetSelectedDrawable = true;
return this;
}

public DrawableSelector setFocusedDrawable(Drawable drawable) {
mFocusedDrawable = drawable;
hasSetFocusedDrawable = true;
return this;
}

public StateListDrawable create() {
StateListDrawable selector = new StateListDrawable();
if (hasSetDisabledDrawable)
selector.addState(new int[]{-android.R.attr.state_enabled}, mDisabledDrawable);
if (hasSetPressedDrawable)
selector.addState(new int[]{android.R.attr.state_pressed}, mPressedDrawable);
if (hasSetSelectedDrawable)
selector.addState(new int[]{android.R.attr.state_selected}, mSelectedDrawable);
if (hasSetFocusedDrawable)
selector.addState(new int[]{android.R.attr.state_focused}, mFocusedDrawable);
selector.addState(new int[]{}, mDefaultDrawable);
return selector;
}

public DrawableSelector setDefaultDrawable(Context context, @DrawableRes int drawableRes) {
return setDefaultDrawable(ContextCompat.getDrawable(context, drawableRes));
}

public DrawableSelector setDisabledDrawable(Context context, @DrawableRes int drawableRes) {
return setDisabledDrawable(ContextCompat.getDrawable(context, drawableRes));
}

public DrawableSelector setPressedDrawable(Context context, @DrawableRes int drawableRes) {
return setPressedDrawable(ContextCompat.getDrawable(context, drawableRes));
}

public DrawableSelector setSelectedDrawable(Context context, @DrawableRes int drawableRes) {
return setSelectedDrawable(ContextCompat.getDrawable(context, drawableRes));
}

public DrawableSelector setFocusedDrawable(Context context, @DrawableRes int drawableRes) {
return setFocusedDrawable(ContextCompat.getDrawable(context, drawableRes));
}
}

/**
* 颜色ColorSelector
* @author hjy
* created at 2017/12/11 22:26
*/
public static final class ColorSelector {

private int mDefaultColor;
private int mDisabledColor;
private int mPressedColor;
private int mSelectedColor;
private int mFocusedColor;

private boolean hasSetDisabledColor = false;
private boolean hasSetPressedColor = false;
private boolean hasSetSelectedColor = false;
private boolean hasSetFocusedColor = false;

private ColorSelector() {
mDefaultColor = Color.BLACK;
mDisabledColor = Color.GRAY;
mPressedColor = Color.BLACK;
mSelectedColor = Color.BLACK;
mFocusedColor = Color.BLACK;
}

public ColorSelector setDefaultColor(@ColorInt int color) {
mDefaultColor = color;
if (!hasSetDisabledColor)
mDisabledColor = color;
if (!hasSetPressedColor)
mPressedColor = color;
if (!hasSetSelectedColor)
mSelectedColor = color;
if (!hasSetFocusedColor)
mFocusedColor = color;
return this;
}

public ColorSelector setDisabledColor(@ColorInt int color) {
mDisabledColor = color;
hasSetDisabledColor = true;
return this;
}

public ColorSelector setPressedColor(@ColorInt int color) {
mPressedColor = color;
hasSetPressedColor = true;
return this;
}

public ColorSelector setSelectedColor(@ColorInt int color) {
mSelectedColor = color;
hasSetSelectedColor = true;
return this;
}

public ColorSelector setFocusedColor(@ColorInt int color) {
mFocusedColor = color;
hasSetFocusedColor = true;
return this;
}

public ColorStateList create() {
int[] colors = new int[]{
hasSetDisabledColor ? mDisabledColor : mDefaultColor,
hasSetPressedColor ? mPressedColor : mDefaultColor,
hasSetSelectedColor ? mSelectedColor : mDefaultColor,
hasSetFocusedColor ? mFocusedColor : mDefaultColor,
mDefaultColor
};
int[][] states = new int[5][];
states[0] = new int[]{-android.R.attr.state_enabled};
states[1] = new int[]{android.R.attr.state_pressed};
states[2] = new int[]{android.R.attr.state_selected};
states[3] = new int[]{android.R.attr.state_focused};
states[4] = new int[]{};
return new ColorStateList(states, colors);
}
}
}


封装完工具类后,简单使用:

LinearLayout ll1 = (LinearLayout) findViewById(R.id.ll1);
ll1.setBackground(Selector.shapeBuild()
.setStrokeWidth(2)
.setCornerRadius(10)
.setDefaultBgColor(Color.WHITE)
.setPressedBgColor(Color.GRAY)
.setSelectedBgColor(Color.RED)
.setDefaultStrokeColor(Color.BLACK)
.setPressedStrokeColor(Color.YELLOW)
.setSelectedStrokeColor(Color.GRAY)
.create());


TextView setShapeAndTextByCode = (TextView) findViewById(R.id.setShapeAndTextByCode);
setShapeAndTextByCode.setBackground(
Selector.shapeBuild()
.setDefaultStrokeColor(Color.GRAY)
.setSelectedStrokeColor(Color.BLACK)
.setPressedStrokeColor(Color.RED)
.setDefaultBgColor(Color.WHITE)
.setSelectedBgColor(Color.RED)
.setPressedBgColor(Color.GRAY)
.setStrokeWidth(2)
.setCornerRadius(10)
.create());
setShapeAndTextByCode.setTextColor(Selector.colorBuild()
.setDefaultColor(Color.BLACK)
.setPressedColor(Color.RED)
.setSelectedColor(Color.WHITE)
.create());


从上面的使用情况,有些人可能会觉得这样需要设置很多属性,觉得跟直接写xml没什么两样,博主也是考虑到了,于是请看下文,自定义TextView、Button、Editext、LinearLayout等。

4、自定义View

说到自定义View有三种实现方式,分别是:组合控件、自绘控件和继承控件。文章中选用第三种继承控件。原因是我们只需要使用setText以及setBackground这两属性,没必要组合控件,也不需要自绘控件。

由于自定义TextView、Button、Editext、LinearLayout比较相似,就选自定义TextView进行分析。

自定义三步起:

第一步:在values文件下新建attrs.xml文件,文件中主要存放自定义的属性。attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTextView">
<!--形状 0 RECTANGLE 1 OVAL 2 LINE 3 RING-->
<attr name="shape" format="enum">
<enum name="rectangle" value="0" />
<!--<enum name="oval" value="1" />-->
<!--<enum name="line" value="2" />-->
<!--<enum name="ring" value="3" />-->
</attr>
<!--线宽度,默认是0-->
<attr name="strokeWidth" format="dimension"/>

<!--圆角的半径,默认是0-->
<attr name="cornerRadius" format="dimension"/>
<!--左上角圆角的半径,默认是0-->
<attr name="TLRadius" format="dimension"/>
<!--右上角圆角的半径,默认是0-->
<attr name="TRRadius" format="dimension"/>
<!--左下角,默认是0-->
<attr name="BLRadius" format="dimension"/>
<!--右下角圆角的半径,默认是0-->
<attr name="BRRadius" format="dimension"/>

<!--注意,这个和下面Drawable只能一个,默认情况是选择颜色-->
<!--默认背景颜色,不设置情况下,透明-->
<attr name="DefaultBgColor" format="color"/>
<!--禁用背景颜色,不设置情况下,透明-->
<attr name="DisabledBgColor" format="color"/>
<!--点击背景颜色,不设置情况下,透明-->
<attr name="PressedBgColor" format="color"/>
<!--选中背景颜色,不设置情况下,透明-->
<attr name="SelectedBgColor" format="color"/>
<!--获取焦点背景颜色,不设置情况下,透明-->
<attr name="FocusedBgColor" format="color"/>

<!--默认边框颜色,不设置情况下,透明-->
<attr name="DefaultStrokeColor" format="color"/>
<!--禁用边框颜色,不设置情况下,透明-->
<attr name="DisabledStrokeColor" format="color"/>
<!--点击边框颜色,不设置情况下,透明-->
<attr name="PressedStrokeColor" format="color"/>
<!--选中边框颜色,不设置情况下,透明-->
<attr name="SelectedStrokeColor" format="color"/>
<!--获取焦点边框颜色,不设置情况下,透明-->
<attr name="FocusedStrokeColor" format="color"/>

<!--默认四个边框全部显示,前提边框的宽度不为0-->
<!--上边框显示,前提边框的宽度不为0-->
<attr name="ShowTopStroke" format="boolean"/>
<!--下边框显示,前提边框的宽度不为0-->
<attr name="ShowBottomStroke" format="boolean"/>
<!--左边框显示,前提边框的宽度不为0-->
<attr name="ShowLeftStroke" format="boolean"/>
<!--右边框显示,前提边框的宽度不为0-->
<attr name="ShowRightStroke" format="boolean"/>

<!--上边框宽度-->
<attr name="TopStrokeWidth" format="dimension"/>
<!--下边框宽度-->
<attr name="BottomStrokeWidth" format="dimension"/>
<!--左边框宽度-->
<attr name="LeftStrokeWidth" format="dimension"/>
<!--右边框宽度-->
<attr name="RightStrokeWidth" format="dimension"/>

<!--默认字体颜色,不设置情况下,黑色-->
<attr name="DefaultColor" format="color"/>
<!--禁用字体颜色,不设置情况下,透明-->
<attr name="DisabledColor" format="color"/>
<!--点击字体颜色,不设置情况下,透明-->
<attr name="PressedColor" format="color"/>
<!--选中字体颜色,不设置情况下,透明-->
<attr name="SelectedColor" format="color"/>
<!--获取焦点字体颜色,不设置情况下,透明-->
<attr name="FocusedColor" format="color"/>

<!--注意,这个和上面BgColor只能一个,默认情况是选择颜色-->
<!--默认背景资源,不设置情况下,黑色-->
<attr name="DefaultDrawable" format="reference"/>
<!--禁用背景资源,不设置情况下,透明-->
<attr name="DisabledDrawable" format="reference"/>
<!--点击背景资源,不设置情况下,透明-->
<attr name="PressedDrawable" format="reference"/>
<!--选中背景资源,不设置情况下,透明-->
<attr name="SelectedDrawable" format="reference"/>
<!--获取焦点背景资源,不设置情况下,透明-->
<attr name="FocusedDrawable" format="reference"/>

<!--设置背景资源来源,默认情况是选择颜色-->
<attr name="BackgroundSource" format="enum">
<enum name="color" value="0" />
<enum name="drawable" value="1" />
</attr>

</declare-styleable>
</resources>


第二步:

新建CustomTextView集成AppCompatTextView,重写三个构造。

/**
* author:hjy
* date:2017/12/12 11:19
* detial:自定义TextView
*/

public class CustomTextView extends AppCompatTextView {
// 线宽 布局默认单位px 转化成dp
private int mStrokeWidth = 0;
// 形状  0 RECTANGLE  只支持长方形、圆形
private int mShape = 0;
// 圆角半径 布局默认单位px 转化成dp
private int mCornerRadius = 0;
// 左上角圆角的半径,默认是0 转化成dp
private int mTLRadius = 0;
// 右上角圆角的半径,默认是0 转化成dp
private int mTRRadius = 0;
// 左下角圆角的半径,默认是0 转化成dp
private int mBLRadius = 0;
// 右下角圆角的半径,默认是0 转化成dp
private int mBRRadius = 0;

// 注意,这个和下面Drawable只能一个,默认情况是选择颜色
// 默认背景颜色,不设置情况下,透明
private int mDefaultBgColor = Color.TRANSPARENT;
// 禁用背景颜色,不设置情况下,透明
private int mDisabledBgColor = Color.TRANSPARENT;
// 点击背景颜色,不设置情况下,透明
private int mPressedBgColor = Color.TRANSPARENT;
// 选中背景颜色,不设置情况下,透明
private int mSelectedBgColor = Color.TRANSPARENT;
// 获取焦点背景颜色,不设置情况下,透明
private int mFocusedBgColor = Color.TRANSPARENT;

// 上边框宽度
private int mTopStrokeWidth = 0;
// 下边框宽度
private int mBottomStrokeWidth = 0;
// 左边框宽度
private int mLeftStrokeWidth = 0;
// 右边框宽度
private int mRightStrokeWidth = 0;

// 默认边框颜色,不设置情况下,透明
private int mDefaultStrokeColor = Color.TRANSPARENT;
// 禁用边框颜色,不设置情况下,透明
private int mDisabledStrokeColor = Color.TRANSPARENT;
// 点击边框颜色,不设置情况下,透明
private int mPressedStrokeColor = Color.TRANSPARENT;
// 选中边框颜色,不设置情况下,透明
private int mSelectedStrokeColor = Color.TRANSPARENT;
// 获取焦点边框颜色,不设置情况下,透明
private int mFocusedStrokeColor = Color.TRANSPARENT;

// 默认四个边框全部显示,前提边框的宽度不为0
// 上边框显示,前提边框的宽度不为0
private boolean mShowTopStroke = true;
// 下边框显示,前提边框的宽度不为0
private boolean mShowBottomStroke = true;
// 左边框显示,前提边框的宽度不为0
private boolean mShowLeftStroke = true;
// 右边框显示,前提边框的宽度不为0
private boolean mShowRightStroke = true;

// 默认字体颜色,不设置情况下,黑色
private int mDefaultColor = Color.BLACK;
// 禁用字体颜色,不设置情况下,透明
private int mDisabledColor = Color.GRAY;
// 点击字体颜色,不设置情况下,透明
private int mPressedColor = Color.BLACK;
// 选中字体颜色,不设置情况下,透明
private int mSelectedColor = Color.BLACK;
// 获取焦点字体颜色,不设置情况下,透明
private int mFocusedColor = Color.BLACK;

// 设置背景资源来源,默认情况是选择颜色 color 0
private int mBackgroundSource = 0;

// 默认背景资源,不设置情况下,透明
private Drawable mDefaultDrawable; // new ColorDrawable(Color.TRANSPARENT)
// 禁用背景资源,不设置情况下,透明
private Drawable mDisabledDrawable;
// 点击背景资源,不设置情况下,透明
private Drawable mPressedDrawable;
// 选中背景资源,不设置情况下,透明
private Drawable mSelectedDrawable;
// 获取焦点背景资源,不设置情况下,透明
private Drawable mFocusedDrawable;

public CustomTextView(Context context) {
this(context, null);
}

public CustomTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); }

public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs, defStyleAttr);
}

/**
* author:hjy on 2017/12/13 14:58
* detial:获取属性
*/
private void getViewAttr(Context context,AttributeSet attrs,int defStyleAttr){
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyleAttr, 0);
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
mShape = array.getInteger(R.styleable.CustomTextView_shape, 0);

mStrokeWidth = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_strokeWidth,0));
mCornerRadius = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_cornerRadius,0));

mTLRadius = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_TLRadius, 0));
mTRRadius = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_TRRadius,0));
mBLRadius = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_BLRadius,0));
mBRRadius = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_BRRadius,0));

mTopStrokeWidth = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_TopStrokeWidth,0));
mBottomStrokeWidth = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_BottomStrokeWidth,0));
mLeftStrokeWidth = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_LeftStrokeWidth,0));
mRightStrokeWidth = parsePxToDp(array.getDimensionPixelSize(R.styleable.CustomTextView_RightStrokeWidth,0));

mDefaultBgColor = array.getColor(R.styleable.CustomTextView_DefaultBgColor,Color.TRANSPARENT);
mDisabledBgColor = array.getColor(R.styleable.CustomTextView_DisabledBgColor,Color.TRANSPARENT);
mPressedBgColor = array.getColor(R.styleable.CustomTextView_PressedBgColor,Color.TRANSPARENT);
mSelectedBgColor = array.getColor(R.styleable.CustomTextView_SelectedBgColor,Color.TRANSPARENT);
mFocusedBgColor = array.getColor(R.styleable.CustomTextView_FocusedBgColor,Color.TRANSPARENT);

mDefaultStrokeColor = array.getColor(R.styleable.CustomTextView_DefaultStrokeColor,Color.TRANSPARENT);
mDisabledStrokeColor = array.getColor(R.styleable.CustomTextView_DisabledStrokeColor,Color.TRANSPARENT);
mPressedStrokeColor = array.getColor(R.styleable.CustomTextView_PressedStrokeColor,Color.TRANSPARENT);
mSelectedStrokeColor = array.getColor(R.styleable.CustomTextView_SelectedStrokeColor,Color.TRANSPARENT);
mFocusedStrokeColor = array.getColor(R.styleable.CustomTextView_FocusedStrokeColor,Color.TRANSPARENT);

mShowTopStroke = array.getBoolean(R.styleable.CustomTextView_ShowTopStroke,true);
mShowBottomStroke = array.getBoolean(R.styleable.CustomTextView_ShowBottomStroke,true);
mShowLeftStroke = array.getBoolean(R.styleable.CustomTextView_ShowLeftStroke,true);
mShowRightStroke = array.getBoolean(R.styleable.CustomTextView_ShowRightStroke,true);

mDefaultColor = array.getColor(R.styleable.CustomTextView_DefaultColor,Color.BLACK);
mDisabledColor = array.getColor(R.styleable.CustomTextView_DisabledColor,mDefaultColor);
mPressedColor = array.getColor(R.styleable.CustomTextView_PressedColor,mDefaultColor);
mSelectedColor = array.getColor(R.styleable.CustomTextView_SelectedColor,mDefaultColor);
mFocusedColor = array.getColor(R.styleable.CustomTextView_FocusedColor,mDefaultColor);

mDefaultDrawable = array.getDrawable(R.styleable.CustomTextView_DefaultDrawable) == null?
colorDrawable:array.getDrawable(R.styleable.CustomTextView_DefaultDrawable);
mDisabledDrawable = array.getDrawable(R.styleable.CustomTextView_DisabledDrawable) == null?
colorDrawable:array.getDrawable(R.styleable.CustomTextView_DisabledDrawable);
mPressedDrawable = array.getDrawable(R.styleable.CustomTextView_PressedDrawable)  == null?
colorDrawable:array.getDrawable(R.styleable.CustomTextView_PressedDrawable);
mSelectedDrawable = array.getDrawable(R.styleable.CustomTextView_SelectedDrawable)  == null?
colorDrawable:array.getDrawable(R.styleable.CustomTextView_SelectedDrawable);
mFocusedDrawable = array.getDrawable(R.styleable.CustomTextView_FocusedDrawable)  == null?
colorDrawable:array.getDrawable(R.styleable.CustomTextView_FocusedDrawable);

mBackgroundSource = array.getInteger(R.styleable.CustomTextView_BackgroundSource, 0);
//最后记得将TypedArray对象回收
array.recycle();
}

private int parsePxToDp(int value){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
}

/**
* 属性初始化
* @author hjy
* created at 2017/12/12 22:01
*/
private void initView(Context context, AttributeSet attrs, int defStyleAttr){
// 获取属性值
getViewAttr(context,attrs,defStyleAttr);

// 设置背景是否是颜色
if (mBackgroundSource == 0){
// 设置字体
this.setTextColor(Selector.colorBuild()
.setDefaultColor(mDefaultColor)
.setDisabledColor(mDisabledColor)
.setPressedColor(mPressedColor)
.setSelectedColor(mSelectedColor)
.setFocusedColor(mFocusedColor)
.create());

// 判断是什么形状 0 RECTANGLE 1 OVAL 2 LINE 3 RING
if (mShape == 0){
Selector.ShapeSelector shapeSelector = Selector.shapeBuild();
// 设置背景颜色
shapeSelector
.setDefaultBgColor(mDefaultBgColor)
.setDisabledBgColor(mDisabledBgColor)
.setPressedBgColor(mPressedBgColor)
.setSelectedBgColor(mSelectedBgColor)
.setFocusedBgColor(mFocusedBgColor)
.setDefaultStrokeColor(mDefaultStrokeColor)
.setDisabledStrokeColor(mDisabledStrokeColor)
.setPressedStrokeColor(mPressedStrokeColor)
.setSelectedStrokeColor(mSelectedStrokeColor)
.setFocusedStrokeColor(mFocusedStrokeColor)
;

shapeSelector.setCornerRadius(mCornerRadius);
if (mTLRadius != 0)
shapeSelector.setTLRadius(mTLRadius);
if (mTRRadius != 0)
shapeSelector.setTRRadius(mTRRadius);
if (mBLRadius != 0)
shapeSelector.setBLRadius(mBLRadius);
if (mBRRadius != 0)
shapeSelector.setBRRadius(mBRRadius);

shapeSelector.setStrokeWidth(mStrokeWidth);
if (mTopStrokeWidth != 0)
shapeSelector.setTopStrokeWidth(mTopStrokeWidth);
if (mBottomStrokeWidth != 0)
shapeSelector.setBottomStrokeWidth(mBottomStrokeWidth);
if (mLeftStrokeWidth != 0)
shapeSelector.setLeftStrokeWidth(mLeftStrokeWidth);
if (mRightStrokeWidth != 0)
shapeSelector.setRightStrokeWidth(mRightStrokeWidth);

shapeSelector
.setShowBottomStroke(mShowBottomStroke)
.setShowLeftStroke(mShowLeftStroke)
.setShowTopStroke(mShowTopStroke)
.setShowRightStroke(mShowRightStroke);

this.setBackground(shapeSelector.create());
}

} else if (mBackgroundSource == 1) { // 设置背景是否是资源
this.setBackground(Selector.drawableBuild()
.setDefaultDrawable(mDefaultDrawable)
.setDisabledDrawable(mDisabledDrawable)
.setPressedDrawable(mPressedDrawable)
.setSelectedDrawable(mSelectedDrawable)
.setFocusedDrawable(mFocusedDrawable)
.create());
}
}
}


第三步:

<com.hjy.customlibrary.view.CustomTextView
android:id="@+id/setShapeAndTextByXml_1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center"
android:textColor="@color/colorBlack"
android:text="xml设置shape、textColor字体"
android:layout_marginTop="10dp"
custom:DefaultBgColor="@color/colorWhite"
custom:SelectedBgColor="@color/colorRed"
custom:PressedBgColor="@color/colorGray"
custom:DefaultStrokeColor="@color/colorGray"
custom:SelectedStrokeColor="@color/colorBlack"
custom:PressedStrokeColor="@color/colorRed"
custom:DefaultColor="@color/colorBlack"
custom:PressedColor="@color/colorRed"
custom:SelectedColor="@color/colorWhite"
custom:strokeWidth="2px"


好了,具体细节请看项目demo,如有疑问可以私聊我,欢迎指错。

github地址:https://github.com/hjy15759633702/CustomView.git
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐