Android 自定义圆角TextView控件 带边框 非shape

Android 自定义圆角TextView控件

在开发中遇到圆角背景大多都是shape资源文件 这样是最简单的方式之一,但是如果很多的圆角,资源文件要不断地创建不同的drawable,最终对打包Apk也不太友好,自定义一个控件来实现View多用

先来看下效果
在这里插入图片描述

自定义一个RectgleTextView

public class RectgleTextView extends AppCompatTextView {
   

    private static final String EMPTY_SPACE = "\u3000";
    private final Context mContext;
    private int type = RECTANGLE;
    private float mRadius;
    private float mTopLeftRadius, mTopRightRadius, mBottomLeftRadius, mBottomRightRadius;
    private int mStrokeColor;
    private int mStrokeWidth;
    private int mSoild;
    private float mTextPadding;
    private CharSequence mTextLeft;
    private CharSequence mTextRight;
    private ColorStateList mIconColor = null;
    private int mCurIconColor;
    private CharSequence iconString;
    private ColorStateList mLeftColor = null;
    private int mCurLeftColor;
    private ColorStateList mRightColor = null;
    private int mCurRightColor;
    private float mLeftSize;
    private float mRightSize;
    private List<SpanContainer> leftContainer;
    private List<SpanContainer> rightContainer;
    private int mTextLeftStyle;
    private int mTextRightStyle;
    private int mTextCenterStyle;
    //icon的index
    private int iconIndex = 0;
    //是否开启计算文字边界,开启后会以最大文字大小为View高度,并且会增加部分文字高度,防止部分英文类型y,g由于基线的原因无法显示完全
    private boolean autoMaxHeight;
    //渐变色
    private ColorStateList startColor = null;
    private ColorStateList centerColor = null;
    private ColorStateList endColor = null;
    //渐变方向
    GradientDrawable.Orientation orientation;

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

    public RectgleTextView(Context context, @Nullable AttributeSet attrs) {
   
        this(context, attrs, 0);
    }

    public RectgleTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        initAttr(context, attrs);
        init();
    }

    private void init() {
   
        initIconFont();
        initShape();
    }

    private void initIconFont() {
   
        iconString = getText().toString();
        int centerSize = iconString.length();
        SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getText());
        if (!TextUtils.isEmpty(mTextLeft) || !TextUtils.isEmpty(mTextRight)) {
   
            //增加空格
            if (!TextUtils.isEmpty(mTextLeft)) {
   
                if (mTextPadding != 0) {
   
                    stringBuilder.insert(0, EMPTY_SPACE);
                    iconIndex++;
                }
                stringBuilder.insert(0, mTextLeft);
                iconIndex += mTextLeft.length();
            }

            if (!TextUtils.isEmpty(mTextRight)) {
   
                if (mTextPadding != 0) {
   
                    stringBuilder.append(EMPTY_SPACE);
                }
                stringBuilder.append(mTextRight);
            }
            /*
             * ==============
             * 设置字和icon间距
             * ==============
             */
            if (mTextPadding != 0) {
   
                //设置字和icon间距
                if (!TextUtils.isEmpty(mTextLeft)) {
   
                    AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan((int) mTextPadding);
                    stringBuilder.setSpan(sizeSpan, iconIndex - 1, iconIndex, Spanned
                            .SPAN_EXCLUSIVE_EXCLUSIVE);
                }

                if (!TextUtils.isEmpty(mTextRight)) {
   
                    AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan((int) mTextPadding);
                    stringBuilder.setSpan(sizeSpan, iconIndex + centerSize, iconIndex +
                            centerSize + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }

            }
            /*
             * ==============
             * 设置左边文字样式
             * ==============
             */
            setLeftTextAttr(stringBuilder);
            /*
             * ==============
             * 设置右边文字样式
             * ==============
             */
            setRightTextAttr(centerSize, stringBuilder);
        }
        /*
         * ==============
         * 设置icon和字的颜色
         * ==============
         */
        if (mIconColor != null) {
   
            int color = mIconColor.getColorForState(getDrawableState(), 0);
            if (color != mCurIconColor) {
   
                mCurIconColor = color;
            }
            ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(mCurIconColor);
            stringBuilder.setSpan(foregroundColorSpan, iconIndex, iconIndex + centerSize, Spanned
                    .SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
   
            mCurIconColor = getCurrentTextColor();
        }
        /*
         * ==============
         * 设置icon的字的样式
         * ==============
         */
        initTextStyle(mTextCenterStyle, stringBuilder, iconIndex, iconIndex + centerSize);
        /*
         * ==============
         * 设置左右Span,记得调用前在**所有方法**前先clearSpan(),不然直接build,上一次的span任然保留着
         * ==============
         */
        if (leftContainer != null) {
   
            for (SpanContainer container : leftContainer) {
   
                for (Object o : container.spans) {
   
                    try {
   
                        stringBuilder.setSpan(o, container.start, container.end, container.flag);
                    } catch (Exception e) {
   
                        //please check invoke clearSpan() method first
                    }
                }
            }
        }
        if (rightContainer != null) {
   
            int start = mTextPadding == 0 ? iconIndex + centerSize : iconIndex + centerSize + 1;
            for (SpanContainer container : rightContainer) {
   
                for (Object o : container.spans) {
   
                    try {
   
                        stringBuilder.setSpan(o, start + container.start, start + container.end,
                                container.flag);
                    } catch (Exception e) {
   
                        //please check invoke clearSpan() method first
                    }
                }
            }
        }

        setText(stringBuilder);
    }

    private void setRightTextAttr(int centerSize, SpannableStringBuilder stringBuilder) {
   
        if (!TextUtils.isEmpty(mTextRight)) {
   
            int start = mTextPadding == 0 ? iconIndex + centerSize : iconIndex + centerSize + 1;
            /*
             * ==============
             * 设置右边字的粗体和斜体
             * ==============
             */
            initTextStyle(mTextRightStyle, stringBuilder, start, stringBuilder.length());
            /*
             * ==============
             * 设置右边字的颜色
             * ==============
             */
            initTextRightColor(stringBuilder, start);
            /*
             * ==============
             * 设置右边字的大小
             * ==============
             */
            initTextSize(stringBuilder, start, stringBuilder.length(), mRightSize, mCurRightColor);
        }
    }

    private void initTextRightColor(SpannableStringBuilder stringBuilder, int start) {
   
        if (mRightColor != null) {
   
            int color = mRightColor.getColorForState(getDrawableState(), 0);
            if (color != mCurRightColor) {
   
                mCurRightColor = color;
            }
            ForegroundColorSpan foregroundRightColor = new ForegroundColorSpan(mCurRightColor);
            stringBuilder.setSpan(foregroundRightColor, start, stringBuilder.length()
                    , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
   
            mCurRightColor = getCurrentTextColor();
        }
    }

    private void setLeftTextAttr(SpannableStringBuilder stringBuilder) {
   
        if (!TextUtils.isEmpty(mTextLeft)) {
   
            int end = mTextPadding == 0 ? iconIndex : iconIndex - 1;
            /*
             * ==============
             * 设置左边字的粗体和斜体
             * ==============
             */
            initTextStyle(mTextLeftStyle, stringBuilder, 0, end);
            /*
             * ==============
             * 设置左边字的颜色
             * ==============
             */
            initTextLeftColor(stringBuilder, end);
            /*
             * ==============
             * 设置左边字的大小
             * ==============
             */
            initTextSize(stringBuilder, 0, end, mLeftSize, mCurLeftColor);
        }
    }

    private void initTextSize(SpannableStringBuilder stringBuilder, int start, int end, float
            textSize, int mCurColor) {
   
        if (textSize != 0) {
   
            CharacterStyle sizeSpan;
            final int gravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
            if (gravity == Gravity.CENTER_VERTICAL) {
   
                sizeSpan = new EasyVerticalCenterSpan(textSize, mCurColor);
            } else {
   
                sizeSpan = new AbsoluteSizeSpan((int) textSize);
            }
            stringBuilder.setSpan(sizeSpan, start, end, Spanned
                    .SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }

    private void initTextLeftColor(SpannableStringBuilder stringBuilder, int end) {
   
        if (mLeftColor != null) {
   
            int color = mLeftColor.getColorForState(getDrawableState(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android诚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值