自定义倒计时跳过按钮

来源:互联网 发布:科比3d模型数据 编辑:程序博客网 时间:2024/06/06 01:06

效果很简单,现在很多APP都有这种效果。

直接上效果图
效果图

先说一下源码地址吧,急用的同学直接拿去用
https://github.com/likangA/CountdownView/tree/master/library/src/main

用法:
XML中直接设置:

        app:center_text="跳过"        app:center_text_color="@color/colorAccent"        app:center_text_size="12sp"        app:duration="5000"        app:progress_color="@color/colorPrimary"        app:progress_light_color="@color/colorAccent" 

Java:

        mCountdownView.setDuration(5000);        mCountdownView.setProgressColor(0xFF3F51B5);        mCountdownView.setProgressLightColor(0xFFFF4081);        mCountdownView.setText("跳过");        mCountdownView.setTextSize(12);        mCountdownView.setTextColor(0xFFFF4081);        mCountdownView.setCountdownListener(new CountdownView.CountdownListener() {            @Override            public void onProgressListener(int progress, boolean isFinish) {                if (isFinish) {                    Toast.makeText(MainActivity.this, "倒计时完成", Toast.LENGTH_SHORT).show();                }            }        });        mCountdownView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(MainActivity.this, "跳过", Toast.LENGTH_SHORT).show();            }        });

第一步、自定义属性

res/values/attrs中添加下面自定义属性

<declare-styleable name="CountdownView">        <attr name="duration" format="float"/>  <!-- 倒计时时长 -->        <attr name="progress_color" format="color"/>  <!-- 默认的时候进度颜色 -->        <attr name="progress_light_color" format="color"/>  <!-- 倒计时转过的进度颜色 -->        <attr name="center_text" format="string"/>  <!-- 中间文字 -->        <attr name="center_text_color" format="color"/>  <!-- 中间文字颜色 -->        <attr name="center_text_size" format="dimension"/>  <!-- 中间文字大小 --></declare-styleable>

获取自定属性

private void obtainAttr(AttributeSet attrs) {    TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CountdownView);    mDuration = (long) (typedArray.getFloat(R.styleable.CountdownView_duration, 3) * 1000);    mProgressColor = typedArray.getColor(R.styleable.CountdownView_progress_color,DEFAULT_PROGRESS_COLOR);    mProgressLightColor = typedArray.getColor(R.styleable.CountdownView_progress_light_color,  DEFAULT_PROGRESS_LIGHT_COLOR);    if (typedArray.hasValue(R.styleable.CountdownView_center_text)) {        mCenterText = typedArray.getString(R.styleable.CountdownView_center_text);        mIsShowInterval = false;    }    mTextColor = typedArray.getColor(R.styleable.CountdownView_center_text_color, DEFAULT_TEXT_COLOR);    mTextSize = typedArray.getDimension(R.styleable.CountdownView_center_text_size, sp2px(getContext(), 12));    typedArray.recycle();}

画笔的基础设置

    private void initPaint() {        //Paint config for default progress.默认进度画笔设置        mProgressPaint = new Paint();        mProgressPaint.setStrokeWidth(mProgressWidth = dip2px(getContext(), 3));        mProgressPaint.setStyle(Paint.Style.STROKE);        //Paint config for light progress.倒计时转过的画笔设置        mProgressLightPaint = new Paint();        mProgressLightPaint.setStrokeWidth(mProgressWidth = dip2px(getContext(), 3));        mProgressLightPaint.setStyle(Paint.Style.STROKE);        //Paint config for text progress.文字画笔设置        mTextPaint = new Paint();        mTextPaint.setStyle(Paint.Style.FILL);    }

第一步的代码在构造函数中调用,第二步的代码在onDraw中调用

第二步、下面开始绘制,首先是默认状态下的进度条

就是一个圆圈

    private void drawProgress(Canvas canvas) {        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - mProgressWidth,                mProgressPaint);    }

这里写图片描述

倒计时转过的圆圈

    private void drawProgressLight(Canvas canvas) {        //画布的方向是从X轴正方形开始为0度,但我们需要的是从Y轴正方向开始,所以画布需要逆时针旋转90度        canvas.save();        canvas.rotate(-90, getWidth() / 2, getHeight() / 2);        RectF progressLightRect = new RectF(mProgressWidth, mProgressWidth,                getWidth() - mProgressWidth, getHeight() - mProgressWidth);        //扫过的角度大小        float sweep = obtainPercent() * 360;        canvas.drawArc(progressLightRect, 0, sweep, false, mProgressLightPaint);        canvas.restore();    }

obtainPercent函数是获取当前百分比进度,就一句话。可以看到红色扫过的长度跟mCurProgress有关

先手动给mCurProgress一个初始值,可以看到已经有了效果

    private float obtainPercent() {        return (float) mCurProgress / 100;    }

这里写图片描述

然后是中间的文字

    private void drawText(Canvas canvas) {        Rect textBound = new Rect();        mTextPaint.getTextBounds(mCenterText, 0, mCenterText.length(), textBound);        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();        //文字垂直居中的y:getHeight() / 2 - fontMetrics.descent + (fontMetrics.descent - fontMetrics.ascent) / 2        canvas.drawText(mCenterText, getWidth() / 2 - textBound.width() / 2,                getHeight() / 2 - fontMetrics.descent + (fontMetrics.descent - fontMetrics.ascent) / 2,                mTextPaint);    }

这里写图片描述

文字垂直居中可以百度一下drawText怎么垂直居中。刚开始我也是很糊涂

第三步、该让红色自动画圆了

上面说道红色扫过的长度跟mCurProgress有关,所以只要能自动改变mCurProgress的值,扫过的红色自然就跟着变了,这里选择了ValueAnimator来控制

public void startAnim() {        final ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);        valueAnimator.setDuration(mDuration);        valueAnimator.setInterpolator(new LinearInterpolator());        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mCurProgress = (int) animation.getAnimatedValue();                //...                invalidate();            }        });        valueAnimator.start();    }

现在调用一下看效果

CountdownView mCountdownView = (CountdownView) findViewById(R.id.countdown);mCountdownView.startAnim();

这里写图片描述

最后就是倒计时结束的监听了,我们用ValueAnimator实现的倒计时,所以监听也应该在ValueAnimator这实现,在ValueAnimator的onAnimationUpdate中添加几行代码即可

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mCurProgress = (int) animation.getAnimatedValue();                mSurplusDuration = mDuration - animation.getCurrentPlayTime();                //进度监听                if (mCountdownListener != null) {                    mCountdownListener.onProgressListener(mCurProgress, mCurProgress == 100);                }                invalidate();            }        });

进度监听接口定义

    public interface CountdownListener {        void onProgressListener(int progress, boolean isFinish);    }

对了,如果想显示倒计时还剩多少秒的话可以去掉文字设置或者setCenterText(null)就行了。怎么实现的很简单,看一下源码就能看懂。效果:
这里写图片描述

好了,就是这么简单
其实学Android以来从来没怎么写过自定义View,博客更是没写过,感觉这篇更像是笔记吧,不过有个好的开端也是好的

0 0
原创粉丝点击