Android自定义控件(入门级)--数字显示器

栏目: IOS · Android · 发布时间: 5年前

内容简介:1.数字为1位,显示圆形2.数字为2位图形拉伸,左右各半圆3.数字大于999,显示999+

需求

1.数字为1位,显示圆形

2.数字为2位图形拉伸,左右各半圆

3.数字大于999,显示999+

4.自定义文字颜色,自定义背景色

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

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

Android自定义控件(入门级)--数字显示器

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大小

Android自定义控件(入门级)--数字显示器

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"/>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

迎接互联网的明天

迎接互联网的明天

邹静 / 电子工业 / 2011-6 / 55.00元

《迎接互联网的明天-玩转3D Web(附盘)》,全书共5章,第1章主要阐述了国内外空前繁荣的3D互联网技术领域,以及这些领域透射出来的潜在商机;第2章主要用当下比较流行的Flash编程语言ActionScript 3,来向大家介绍面向对象编程语言的思想概念,以及一些3D渲染技术的入门知识;第3章注重建模知识的运用,主要运用WireFusion和3ds Max来制作3D网页;第4章主要介绍3D游戏编......一起来看看 《迎接互联网的明天》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具