自定义圆环倒计时
来源:互联网 发布:ofo登录 网络请求超时 编辑:程序博客网 时间:2024/05/22 19:00
public class CountDownView extends View{ private static int defaultCircleSolideColor = Color.BLUE; private static int defaultCircleStrokeColor = Color.WHITE;//最底层的颜色 private static int defaultCircleStrokeWidth = 10; private static int defaultCircleRadius = 60; private static int progressColor = Color.YELLOW;//进度条的颜色 private static int progressWidth = 11;//>defaultCircleStrokeWidth private static int smallCircleSolideColor = Color.BLACK; private static int smallCircleStrokeColor = Color.WHITE; private static float smallCircleStrokeWidth = 8; private static float smallCircleRadius = 30; private static int textColor = Color.WHITE;//BLACK private static float textSize = 30; private static Paint defaultCriclePaint; private static Paint progressPaint; private static Paint textPaint; private static float currentAngle; public static String textDesc; public static long countdownTime; private static int mStartSweepValue = -90; //设置画布圆形背景 private Paint backgroundPaint; public static ValueAnimator animator; public CountDownView(Context context) { super(context); } public CountDownView(Context context, AttributeSet attrs) { super(context, attrs); initStyle(attrs); setPaint(); } public CountDownView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //获取自定义属性 initStyle(attrs); setPaint(); } private void initStyle(AttributeSet attrs){ TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CountDownProgress); int indexCount = typedArray.getIndexCount(); for(int i=0;i<indexCount;i++){ int attr = typedArray.getIndex(i); switch (attr){ case R.styleable.CountDownProgress_default_circle_solide_color: defaultCircleSolideColor = typedArray.getColor(attr, defaultCircleSolideColor); break; case R.styleable.CountDownProgress_default_circle_stroke_color: defaultCircleStrokeColor = typedArray.getColor(attr, defaultCircleStrokeColor); break; case R.styleable.CountDownProgress_default_circle_stroke_width: defaultCircleStrokeWidth = (int) typedArray.getDimension(attr, defaultCircleStrokeWidth); break; case R.styleable.CountDownProgress_default_circle_radius: defaultCircleRadius = (int) typedArray.getDimension(attr, defaultCircleRadius); break; case R.styleable.CountDownProgress_progress_color: progressColor = typedArray.getColor(attr, progressColor); break; case R.styleable.CountDownProgress_progress_width: progressWidth = (int) typedArray.getDimension(attr, progressWidth); break; case R.styleable.CountDownProgress_small_circle_solide_color: smallCircleSolideColor = typedArray.getColor(attr, smallCircleSolideColor); break; case R.styleable.CountDownProgress_small_circle_stroke_color: smallCircleStrokeColor = typedArray.getColor(attr, smallCircleStrokeColor); break; case R.styleable.CountDownProgress_small_circle_stroke_width: smallCircleStrokeWidth = (int) typedArray.getDimension(attr, smallCircleStrokeWidth); break; case R.styleable.CountDownProgress_small_circle_radius: smallCircleRadius = (int) typedArray.getDimension(attr, smallCircleRadius); break; case R.styleable.CountDownProgress_text_color: textColor = typedArray.getColor(attr, textColor); break; case R.styleable.CountDownProgress_text_size: textSize = (int) typedArray.getDimension(attr, textSize); break; } } typedArray.recycle(); } private void setPaint() { //默认圆 defaultCriclePaint = new Paint(); defaultCriclePaint.setAntiAlias(true);//抗锯齿 defaultCriclePaint.setDither(true);//防抖动 defaultCriclePaint.setStyle(Paint.Style.STROKE); defaultCriclePaint.setStrokeWidth(defaultCircleStrokeWidth); defaultCriclePaint.setColor(defaultCircleStrokeColor);//这里先画边框的颜色,后续再添加画笔画实心的颜色 //默认圆上面的进度弧度 progressPaint = new Paint(); progressPaint.setAntiAlias(true); progressPaint.setDither(true); progressPaint.setStyle(Paint.Style.STROKE); progressPaint.setStrokeWidth(progressWidth); progressPaint.setColor(progressColor); progressPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷样式 //文字画笔 textPaint = new Paint(); textPaint.setAntiAlias(true); textPaint.setDither(true); textPaint.setStyle(Paint.Style.FILL); textPaint.setColor(textColor); textPaint.setTextSize(textSize); backgroundPaint=new Paint(); backgroundPaint.setAntiAlias(true);//抗锯齿 backgroundPaint.setDither(true);//防抖动 backgroundPaint.setStyle(Paint.Style.FILL); backgroundPaint.setStrokeWidth(defaultCircleStrokeWidth); backgroundPaint.setColor(progressColor);//这里先画边框的颜色,后续再添加画笔画实心的颜色 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.translate(getPaddingLeft(), getPaddingTop()); //背景圆 canvas.drawCircle(defaultCircleRadius, defaultCircleRadius, defaultCircleRadius, backgroundPaint); //画默认圆 canvas.drawCircle(defaultCircleRadius, defaultCircleRadius, defaultCircleRadius, defaultCriclePaint); //画进度圆弧 //currentAngle = getProgress()*1.0f/getMax()*360;recf适用于划出一块绘制的区域mStartSweepValue是开始的位置 canvas.drawArc(new RectF(0, 0, defaultCircleRadius*2, defaultCircleRadius*2),mStartSweepValue, 360*currentAngle,false,progressPaint); //画中间文字 // String text = getProgress()+"%"; //获取文字的长度的方法 float textWidth = textPaint.measureText(textDesc); float textHeight = (textPaint.descent() + textPaint.ascent()) / 2; canvas.drawText(textDesc, defaultCircleRadius - textWidth/2, defaultCircleRadius - textHeight, textPaint); canvas.restore(); } /** * 如果该View布局的宽高开发者没有精确的告诉,则需要进行测量,如果给出了精确的宽高则我们就不管了 * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize; int heightSize; int strokeWidth = Math.max(defaultCircleStrokeWidth, progressWidth); //精确指定宽高 if(widthMode != MeasureSpec.EXACTLY){ widthSize = getPaddingLeft() + defaultCircleRadius*2 + strokeWidth + getPaddingRight(); widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); } if(heightMode != MeasureSpec.EXACTLY){ heightSize = getPaddingTop() + defaultCircleRadius*2 + strokeWidth + getPaddingBottom(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } //属性动画 public void startCountDownTime(final OnCountdownFinishListener countdownFinishListener){ setClickable(true); animator = ValueAnimator.ofFloat(0, 1.0f); //动画时长,让进度条在CountDown时间内正好从0-360走完,这里由于用的是CountDownTimer定时器,倒计时要想减到0则总时长需要多加1000毫秒,所以这里时间也跟着+1000ms animator.setDuration(countdownTime );//+ 1000 animator.setInterpolator(new LinearInterpolator());//匀速 animator.setRepeatCount(0);//表示不循环,-1表示无限循环 //值从0-1.0F 的动画,动画时长为countdownTime,ValueAnimator没有跟任何的控件相关联,那也正好说明ValueAnimator只是对值做动画运算,而不是针对控件的,我们需要监听ValueAnimator的动画过程来自己对控件做操作 //添加监听器,监听动画过程中值的实时变化(animation.getAnimatedValue()得到的值就是0-1.0) animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { /** * 这里我们已经知道ValueAnimator只是对值做动画运算,而不是针对控件的,因为我们设置的区间值为0-1.0f * 所以animation.getAnimatedValue()得到的值也是在[0.0-1.0]区间,而我们在画进度条弧度时,设置的当前角度为360*currentAngle, * 因此,当我们的区间值变为1.0的时候弧度刚好转了360度 */ currentAngle = (float) animation.getAnimatedValue(); // Log.e("currentAngle",currentAngle+""); invalidate();//实时刷新view,这样我们的进度条弧度就动起来了 } }); //开启动画 animator.start(); //还需要另一个监听,监听动画状态的监听器 animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { //倒计时结束的时候,需要通过自定义接口通知UI去处理其他业务逻辑 if(countdownFinishListener != null){ countdownFinishListener.countdownFinished(); } if(countdownTime > 0){ setClickable(true); }else{ setClickable(false); } } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); //调用倒计时操作 countdownMethod(); } public CountDownTimer timer; //倒计时的方法 private void countdownMethod(){ timer= new CountDownTimer(countdownTime+1000, 1000) { @Override public void onTick(long millisUntilFinished) { // Log.e("time",countdownTime+""); countdownTime = countdownTime-1000; textDesc = "跳过("+((countdownTime/1000)) + ")"; //countdownTime = countdownTime-1000; //刷新view invalidate(); } @Override public void onFinish() { //textDesc = 0 + "″"; //刷新view// textDesc="跳过(0)";// invalidate(); } }.start(); } public void setCountdownTime(long countdownTime){ this.countdownTime = countdownTime; textDesc = countdownTime / 1000 + "″"; } public interface OnCountdownFinishListener{ void countdownFinished(); }}<com.bawei.macbook.moni.persenter.CountDownView android:id="@+id/countdwonview" android:layout_width="90dp" android:layout_height="100dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:paddingTop="35dp" android:paddingRight="10dp" android:paddingLeft="10dp" />
阅读全文
0 0
- 自定义圆环倒计时
- 自定义圆环倒计时
- 自定义圆环view 倒计时控件
- 属性动画+自定义view进度圆环的倒计时
- CSS3圆环倒计时效果
- CSS3圆环倒计时效果
- 自定义圆环
- 自定义圆环
- 自定义圆环样式
- 圆环百分比自定义View
- 自定义圆环1
- 简单自定义圆环
- 自定义进度圆环
- 自定义圆环进度
- android 自定义圆环
- 自定义圆环进度条
- 自定义圆环进度条
- 自定义view-圆环
- 欢迎使用CSDN-markdown编辑器
- Hbase架构体系与设计模型
- SDUT-1272 面向对象程序设计上机练习十(运算符重载)
- myeclipse maven项目没有maven depencies
- 播放歌曲
- 自定义圆环倒计时
- codeforces 625B KMP水题
- pwn实战的一些手法
- 考后梳理之数据结构
- 50天iOS挑战(Swift)
- Tablayout与viewpager的联动
- 模糊查询+删除+修改+添加习题
- 【JavaEE学习笔记】Servlet_03_重定向,请求对象,请求域
- ADT打包本地扩展ANE指令