教你玩转自定义View—手撸一个倒计时控件如此简单

在一个APP启动的时候呢,通常常常见到倒计时3秒或几秒的场景,在这个场景中,也常常看到一个有动画加载的view,效果图以下:git

倒计时效果图
倒计时效果图

分析

正所谓知己知彼百战百胜,因此咱们每去作一件事情以前都要去花费必定的时间去了解一些相关的东西。那么这样的一个效果呢其实不难,咱们只需两个东西便可实现。——canvas和属性动画。github

1.自定义咱们须要的属性:

那么为了考虑扩展性,那么有些属性呢咱们不能写死,自定义属性是最好的选择!首先在values文件夹下新建文件attrs.xmlcanvas

<declare-styleable name="CountDownView">
        <!--view半径-->
        <attr name="cd_circle_radius" format="dimension" />
        <!--画笔宽度-->
        <attr name="cd_arc_width" format="dimension" />
        <!--画笔颜色-->
        <attr name="cd_arc_color" format="color" />
        <!--背景颜色-->
        <attr name="cd_bg_color" format="color" />
        <!--字体颜色-->
        <attr name="cd_text_color" format="color" />
        <!--字体尺寸-->
        <attr name="cd_text_size" format="dimension" />
        <!--动画执行时长-->
        <attr name="cd_animator_time" format="integer" />
        <!--时间单位-->
        <attr name="cd_animator_time_unit" format="string" />
        <!--动画进退方式-->
        <attr name="cd_retreat_type" format="enum">
            <!--外层的圆弧逐渐变长-->
            <enum name="forward" value="1" />
            <!--外层的圆弧逐渐减短-->
            <enum name="back" value="2" />
        </attr>
        <!--加载进度的开始位置-->
        <attr name="cd_location" format="enum">
            <enum name="left" value="1" />
            <enum name="top" value="2" />
            <enum name="right" value="3" />
            <enum name="bottom" value="4" />
        </attr>
    </declare-styleable>复制代码

而后在自定义View中获取并设置这些属性:
首先,来声明和获取定义好的属性:bash

private Paint mPaintBackGround;//背景画笔
    private Paint mPaintArc;//圆弧画笔
    private Paint mPaintText;//文字画笔
    private int mRetreatType;//圆弧绘制方式(增长和减小)
    private float mPaintArcWidth;//最外层圆弧的宽度
    private int mCircleRadius;//圆圈的半径
    private int mPaintArcColor = Color.parseColor("#3C3F41");//初始值
    private int mPaintBackGroundColor = Color.parseColor("#55B2E5");//初始值
......复制代码

获取这些属性值:微信

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CountDownView);
mRetreatType = array.getInt(R.styleable.CountDownView_cd_retreat_type, 1);
location = array.getInt(R.styleable.CountDownView_cd_location, 1);复制代码

初始化画笔等操做:ide

2.画出须要的效果:画圆弧,画字体,画背景

这里咱们使用cancas的drawArc()方法,不了解这个方法是什么意思的请跳至此处查看详细解释~drawArc()方法详细介绍字体

环形进度
环形进度

3.改变属性值,从新绘制

4.接口回调。

这一步就很简单了,只要监听动画执行结束就是完成了加载,因此咱们先来写一个接口。动画

private OnLoadingFinishListener loadingFinishListener;

    public void setOnLoadingFinishListener(OnLoadingFinishListener listener) {
        this.loadingFinishListener = listener;
    }

    public interface OnLoadingFinishListener {
        void finish();
    }复制代码

在对应的Activity中回调接口就能够了。ui

OK,到这里就算所有结束了,下面是部分源码:this

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //由于必须是圆形的view,因此在这里从新赋值
        setMeasuredDimension(mCircleRadius * 2, mCircleRadius * 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画北景园
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2 - mPaintArcWidth, mPaintBackGround);
        //画圆弧
        RectF rectF = new RectF(0 + mPaintArcWidth / 2, 0 + mPaintArcWidth / 2
                , mWidth - mPaintArcWidth / 2, mHeight - mPaintArcWidth / 2);
        canvas.drawArc(rectF, startAngle, mSweepAngle, false, mPaintArc);
        //画文字
        float mTetxWidth = mPaintText.measureText(mText, 0, mText.length());
        float dx = mWidth / 2 - mTetxWidth / 2;
        Paint.FontMetricsInt fontMetricsInt = mPaintText.getFontMetricsInt();
        float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
        float baseLine = mHeight / 2 + dy;
        canvas.drawText(mText, dx, baseLine, mPaintText);

    }复制代码

博客地址:

www.jianshu.com/p/2b5ef5e18…

项目地址:

github.com/SuperKotlin…

相信本身,没有作不到的,只有想不到的

若是你以为此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

技术+职场
技术+职场
相关文章
相关标签/搜索