搞定字体样式、背景的工具类(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
相关文章推荐
- selector和shape,实现button上既有样式,也有背景
- Shape样式、Selector触摸反馈效果工具
- ios--状态栏统一样式:黑色背景白色字体
- 字体、文本、背景、列表样式和超链接(2)
- Android 背景样式shape -- oval椭圆、圆
- R语言工具学习笔记(一)修改字体及背景
- Drawable Resources selector和shape 用法
- phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
- 黄聪:phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
- 3.CSS基本样式:背景、文本、字体、链接、列表、表格、轮廓
- 用js操作table、tr、td 「字体样式及TD背景图片」
- java代码中实现android背景选择的selector-StateListDrawable的应用
- ios 改变导航返回按钮的字体样式以及背景图片
- Android Studio在drawable文件夹创建xml的shape、selector等文件
- android:改动PagerTabStrip中的背景颜色,标题字体的样式、颜色和图标以及指示条的颜色
- android使用selector修改TextView中的字体颜色和背景颜色
- android样式学习(一) 使用selector改变来动态改变背景颜色
- java代码中实现android背景选择的selector-StateListDrawable的应用
- Android:背景选择器selector及shape详解
- Android字体多样式和动画TextDrawable