Android自定义View倒计时圆

本文实例为大家分享了Android自定义View倒计时圆的具体代码,供大家参考,具体内容如下

创建attr

<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CountDownView"> <!--颜色--> <attr name="ringColor" format="color" /> <!-- 进度文本的字体大小 --> <attr name="progressTextSize" format="dimension" /> <!-- 圆环宽度 --> <attr name="ringWidth" format="float" /> <!--进度文本颜色--> <attr name="progressTextColor" format="color"/> <!--倒计时--> <attr name="countdownTime" format="integer"/> </declare-styleable> </resources>

创建DisplayUtil 类

import android.content.Context; /** * Created by 王 on 2017/10/21. */ public class DisplayUtil { /** * 将px装换成dp,保证尺寸不变 * @param context * @param pxValue * @return */ public static int px2dp(Context context, float pxValue){ float density = context.getResources().getDisplayMetrics().density;//得到设备的密度 return (int) (pxValue/density+0.5f); } public static int dp2px(Context context,float dpValue){ float density = context.getResources().getDisplayMetrics().density; return (int) (dpValue*density+0.5f); } public static int px2sp(Context context,float pxValue){ float scaleDensity = context.getResources().getDisplayMetrics().scaledDensity;//缩放密度 return (int) (pxValue/scaleDensity+0.5f); } public static int sp2px(Context context,float spValue) { float scaleDensity = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue*scaleDensity+0.5f); } }

继承View

import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.LinearInterpolator; /** * Created by 王 on 2017/10/21. */ public class CountDownView extends View{ //圆轮颜色 private int mRingColor; //圆轮宽度 private float mRingWidth; //圆轮进度值文本大小 private int mRingProgessTextSize; //宽度 private int mWidth; //高度 private int mHeight; private Paint mPaint; //圆环的矩形区域 private RectF mRectF; // private int mProgessTextColor; private int mCountdownTime; private float mCurrentProgress; private OnCountDownFinishListener mListener; public CountDownView(Context context) { this(context, null); } public CountDownView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CountDownView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CountDownView); mRingColor = a.getColor(R.styleable.CountDownView_ringColor, context.getResources().getColor(R.color.colorAccent)); mRingWidth = a.getFloat(R.styleable.CountDownView_ringWidth, 40); mRingProgessTextSize = a.getDimensionPixelSize(R.styleable.CountDownView_progressTextSize, DisplayUtil.sp2px(context, 20)); mProgessTextColor = a.getColor(R.styleable.CountDownView_progressTextColor, context.getResources().getColor(R.color.colorAccent)); mCountdownTime = a.getInteger(R.styleable.CountDownView_countdownTime, 10); a.recycle(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setAntiAlias(true); this.setWillNotDraw(false); } public void setCountdownTime(int mCountdownTime) { this.mCountdownTime = mCountdownTime; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); mWidth = getMeasuredWidth(); mHeight = getMeasuredHeight(); mRectF = new RectF(0 + mRingWidth / 2, 0 + mRingWidth / 2, mWidth - mRingWidth / 2, mHeight - mRingWidth / 2); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** *圆环 */ //颜色 mPaint.setColor(mRingColor); //空心 mPaint.setStyle(Paint.Style.STROKE); //宽度 mPaint.setStrokeWidth(mRingWidth); canvas.drawArc(mRectF, -90, mCurrentProgress - 360, false, mPaint); //绘制文本 Paint textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); String text = mCountdownTime - (int) (mCurrentProgress / 360f * mCountdownTime) + ""; textPaint.setTextSize(mRingProgessTextSize); textPaint.setColor(mProgessTextColor); //文字居中显示 Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt(); int baseline = (int) ((mRectF.bottom + mRectF.top - fontMetrics.bottom - fontMetrics.top) / 2); canvas.drawText(text, mRectF.centerX(), baseline, textPaint); } private ValueAnimator getValA(long countdownTime) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100); valueAnimator.setDuration(countdownTime); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setRepeatCount(0); return valueAnimator; } /** * 开始倒计时 */ public void startCountDown() { setClickable(false); ValueAnimator valueAnimator = getValA(mCountdownTime * 1000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float i = Float.valueOf(String.valueOf(animation.getAnimatedValue())); mCurrentProgress = (int) (360 * (i / 100f)); invalidate(); } }); valueAnimator.start(); valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //倒计时结束回调 if (mListener != null) { mListener.countDownFinished(); } setClickable(true); } }); } public void setAddCountDownListener(OnCountDownFinishListener mListener) { this.mListener = mListener; } public interface OnCountDownFinishListener { void countDownFinished(); } }

布局

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.circulardemo.MainActivity"> <com.example.circulardemo.CountDownView android:id="@+id/cdv" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>

Mainactivity

import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CountDownView countDownView = (CountDownView) findViewById(R.id.cdv); //启动 countDownView.startCountDown(); countDownView.setAddCountDownListener(new CountDownView.OnCountDownFinishListener() { @Override public void countDownFinished() { Toast.makeText(MainActivity.this, "倒计时结束", Toast.LENGTH_SHORT).show(); } }); } }

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

时间: 2024-09-15 01:48:20

Android自定义View倒计时圆的相关文章

Android自定义View圆形和拖动圆、跟随手指拖动效果

单纯的自定义一个圆非常简单 只需要几步就完成 拖动圆添加实现触摸事件即可 我在第一次自定义View圆遇到的几个Bug: 1.拖动圆的话在xml里面设置的自定义圆的宽和高是它能活动的空间的大小 不是圆控件的大小 如果你定义了100dp 拖动它的时候超过100dp这个距离这个圆就会看不见 就像下面这样 如果想活动于整个屏幕直接给宽和高match_parent属性就好了 2.我在定义充满属性match_parent的时候运行会报错,什么方法都用了就是不行,耐心等待过一会就好了-有可能是studio没来

Android自定义view圆并随手指移动

本文实例为大家分享了Android自定义view圆并随手指移动的具体代码,供大家参考,具体内容如下 main代码 public class MainActivity extends AppCompatActivity { private int screenW; //屏幕宽度 private int screenH; //屏幕高度 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(saved

Android 自定义View之倒计时实例代码

Android 自定义View之倒计时实例代码 需求: 大多数app在注册的时候,都有一个获取验证码的按钮,点击后,访问接口,最终用户会收到短信验证码.为了不多次写这个获取验证码的接口,下面将它自定义成一个view,方便使用. 分析一下,这是一个TextView,点击的时候变色,不能再点击,同时里面的倒计时开始显示.那么就有了下面的代码 代码: /** * 通过selector选择器来改变背景,其中倒计时运行时为android:state_enabled="true", * 不显示倒计

Android自定义View 实现闹钟唤起播放闹钟铃声功能_Android

先上图看一下闹钟唤期页面的效果 实现的功能: 1:转动的图片根据天气情况更换 2:转动时间可以设置,转动结束,闹铃声音就结束 3:光圈颜色渐变效果 直接上代码啦: package com.yuekong.sirius.extension.customview; import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Context; import andro

Android自定义View之使用贝塞尔曲线实现流量进度条

第一次写带图片的博客,多少还是有点紧张,效果不好,请将就着看,前面的图是今天要写的控件的效果图,元素不多,分别是一个按钮和一个自定义的控件. 在此以前,我看过许多的书,比如<Android群英传>.<第一行代码>等,也看了很多大神的博客,但是即便是这样,当我看到这么多代码的时候,一直都没有真正的动手去敲过这些代码,以至于我总是觉得自定义View是一个多么高深莫测的技术,我们这些小白是难以触及的,但是当昨晚看了一篇鸡汤之后,觉得人还是要学会专注,要耐得住寂寞,要沉得住气.所以在未来的

Android自定义View之弧线展示图

前面我也写了有几个自定义进度的控件,那么,今天,我再加一个控件,原理跟前面讲的差不多,先看看效果: 这个是一个以弧线为依托的进度控件,主要包括了两个圆弧.一个圆.一个文本. 当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码. 新建一个类,继承自View,实现三个构造方法,接着定义变量,初始化变量的数据.代码如下: Paint mArcPaint, mCirclePaint, mTextPaint, mPaint; length; mRadius; mCircle

Android自定义View之仿QQ等级天数进度

最近一直都在看自定义View这一块.差不多一个星期了吧.这个星期坚持每天更新博客,感觉自己的技术也有点突破,对自定义View的计算也有了更深的认识. 今天坐地铁玩手机的时候,看到手机一个成长天数进度的控件,觉得挺有意思的,于是想自己也写一个.效果如下: 由图可以知道,这里面有很多个元素,首先是背景的矩形区域,其次就是两个环形,然后三个Text文本.其实不复杂,我们一点一点的去实现. 首先呢,画矩形背景.这里用到一个RectF的类,这个类包含一个矩形的四个单精度浮点坐标.矩形通过上下左右4个边的坐

Android自定义View之仿vivo i管家病毒扫描动画效果

技术是永无止境的,如果真的爱技术,那就勇敢的坚持下去.我很喜欢这句话,当我在遇到问题的时候.当我觉得代码枯燥的时候,我就会问自己,到底是不是真的热爱技术,这个时候,我心里总是起着波澜,我的答案是肯定的,我深深的爱着这门技术. 今天我们继续聊聊Android的自定义View系列.先看看效果吧: 这个是我手机杀毒软件的一个动画效果,类似于雷达搜索,所以用途还是很广泛的,特别是先了解一下这里的具体逻辑和写法,对技术的进步一定很有用. 先简单的分析一下这里的元素,主要有四个圆.一个扇形.还有八条虚线.当

Android自定义View之圆形进度条总结

最近撸了一个圆形进度条的开源项目,算是第一次完完整整的使用自定义 View .在此对项目开发思路做个小结,欢迎大家 Star 和 Fork. 该项目总共实现了三种圆形进度条效果 CircleProgress:圆形进度条,可以实现仿 QQ 健康计步器的效果,支持配置进度条背景色.宽度.起始角度,支持进度条渐变 DialProgress:类似 CircleProgress,但是支持刻度 WaveProgress:实现了水波纹效果的圆形进度条,不支持渐变和起始角度配置,如需此功能可参考 CircleP