美文网首页Android自定义View
Android自定义控件之数字显示

Android自定义控件之数字显示

作者: e4e52c116681 | 来源:发表于2018-12-03 14:42 被阅读387次
    需求

    1.数字为1位,显示圆形
    2.数字为2位图形拉伸,左右各半圆
    3.数字大于999,显示999+
    4.自定义文字颜色,自定义背景色

    效果(好吧,看起来挺low的)

    本身并不复杂,不过作为一道计算题还是很不错的

    效果.png
    1.自定义属性
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--计数TextView-->
        <declare-styleable name="CountTextView">
            <attr name="z_ctv_font_size" format="reference|dimension"/>
            <attr name="z_ctv_num" format="integer"/>
            <attr name="z_bg_color" format="reference|color"/>
            <attr name="z_txt_color" format="reference|color"/>
        </declare-styleable>
    </resources>
    
    2.分析

    使用圆角矩形来画背景,Paint.getTextBounds来获取文字边界矩形
    1).先绘制文字,将文字左顶点与屏幕左顶点重合
    2).通过计算,画出一个数时的圆角矩形两个顶点(如下图)
    3).通过数字位数来控制圆角矩形两顶点的X
    4).通过画布平移让圆角矩形左顶点处于画布顶点
    5).计算圆角矩形的宽高,设置View大小

    IMG20181203130904.jpg
    public class CountTextView extends View {
        private int mCtvFontSize = sp(100);
        private int mCtvNum = 5;
        private int mCtvBgColor = 0xffBFF3F7;
        private int mCtvTxtColor = Color.WHITE;
        private Paint mPaint;//主画笔
        private Paint mTxtPaint;
        private Rect mRect;
        private String mStr;
        private int mOffSet;
    
        public CountTextView(Context context) {
            this(context, null);
        }
    
        public CountTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CountTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CountTextView);
            mCtvFontSize = (int) a.getDimension(R.styleable.CountTextView_z_ctv_font_size, mCtvFontSize);
            mCtvNum = a.getInteger(R.styleable.CountTextView_z_ctv_num, mCtvNum);
            mCtvTxtColor = a.getColor(R.styleable.CountTextView_z_txt_color, mCtvTxtColor);
            mCtvBgColor = a.getColor(R.styleable.CountTextView_z_bg_color, mCtvBgColor);
            a.recycle();
            init();
        }
    
        private void init() {
            //初始化主画笔
            mTxtPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mTxtPaint.setColor(mCtvTxtColor);
            mTxtPaint.setTextSize(mCtvFontSize);
    
            mRect = new Rect();
            mStr = mCtvNum + "";
            if (mCtvNum >= 1000) {
                mStr = "999+";
            }
            mTxtPaint.getTextBounds(mStr, 0, mStr.length(), mRect);
            int AChartLen = mRect.width() / mStr.length();
            mOffSet = (int) ((mStr.length() - 1) * AChartLen * 0.7f);
    
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(mCtvBgColor);
            mPaint.setStrokeWidth(mRect.height());
            mPaint.setStrokeCap(Paint.Cap.ROUND);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //文字左侧距圆心的偏移
            int offsetX = mRect.height() - mRect.width() / 2 + mOffSet;
            setMeasuredDimension(2 * offsetX + mRect.width(), 2 * mRect.height());
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save();
            int offsetX = mRect.height() - mRect.width() / 2 + mOffSet;
            canvas.translate(offsetX, mRect.height() / 2);
            //圆角矩形左上点
            int topX = mRect.width() / 2 - mRect.height();
            int topY = -mRect.height() / 2;
            //圆角矩形右下点
            int bottomX = mRect.height() + mRect.width() / 2;
            int bottomY = mRect.height() / 2 + mRect.height();
            
            canvas.drawRoundRect(topX - mOffSet, topY, bottomX + mOffSet, bottomY,
                    mRect.height(), mRect.height(), mPaint);
    
            canvas.drawText(mStr, 0, mRect.height(), mTxtPaint);
            canvas.restore();
        }
    
        private int sp(float sp) {
            return (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
        }
    }
    
    3.使用
    <com.toly1994.c.view.CountTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:z_ctv_font_size="40sp"
        app:z_ctv_num="30"/>
    

    相关文章

      网友评论

        本文标题:Android自定义控件之数字显示

        本文链接:https://www.haomeiwen.com/subject/rcuycqtx.html