Android仿小米安全中心检测进度条效果

模仿小米安全中心检测效果

废话少说,咱们先上效果图:

github地址: https://github.com/niniloveyou/GradeProgressView

这个效果的使用场景并不多,主要是各种检测的时候,比如垃圾清理,手机安全检测, 当然如果你不嫌弃这个效果丑, 也可以用作进度条。哈哈。

下面说点干货分析下这个效果怎么实现:

拿到这个效果首先想想主要有哪些技术难点:

1.进度条

2.中间的指针怎么弄

1.进度条

有人说进度条还不容易吗? 就这样写:

mPaint.setPathEffect(new DashPathEffect(new float[]{dashWith, dashSpace}, 。。。)); canvas.drawArc(mRectF, 135, 270, false, mPaint); mPaint.setColor(Color.WHITE); canvas.drawArc(mRectF, 135, degree, false, mPaint);

设置个PathEffect
然后画个圆弧,给画笔设置颜色然后根据进度,算出角度, 然后再画出一个圆弧,覆盖第一个圆弧的部分不就行了。废话这么多。
不过我想说的too young too simple. 当时我也是这样想的,于是就实现吧! 做好了先画个50% (也就是第二个圆弧覆盖第一个圆弧的一半)试试,不错啊perfect看来是这样的, 再来个30%试试尼玛不对啊, 怎么小格子没有重合,有点错位啊。MDZZ

后来想了一个简单点的办法,不覆盖,画两个圆弧, 但是这两个圆弧是对接起来的。 比如第一个圆弧,画一半,第二个画一半。

//draw background arc canvas.drawArc(mRectF, 135 + degree, 270 - degree, false, mPaint); //draw progress arc canvas.drawArc(mRectF, 135, degree, false, mProgressPaint);

2.中间的指针怎么弄

先画出指针的路径

mPointerPath = new Path(); mPointerPath.moveTo(centerX + pointRadius, centerY - 7); mPointerPath.lineTo(centerX + pointRadius, centerY + 7); mPointerPath.lineTo(mRectF.right - pointGap - lineWidth / 2,centerY); mPointerPath.lineTo(centerX + pointRadius, centerY - 7); mPointerPath.close();

在中心draw一个小圆
然后draw指针,这样当画布旋转时指针自然也就旋转了,不懂得要去看看canvas.save(), canvas.restore()的作用

//draw pointer canvas.drawCircle(centerX, centerY, pointRadius,mInnerCirclePaint); canvas.save(); canvas.rotate(135 + degree, centerX, centerY); canvas.drawPath(mPointerPath, mPointerPaint); canvas.restore();

下面上完整代码:

package deadline.grade; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.os.Build; import android.support.annotation.IntRange; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; /** * @author deadline * @time 2016/9/24 */ public class GradeProgressView extends View { private static final String TAG = GradeProgressView.class.getSimpleName(); private static final int DEFAULT_PROGRESS_COLOR = Color.WHITE; private static final int DEFAULT_BACKGROUND_COLOR = 0x5AFFFFFF; private int mBackgroundColor = DEFAULT_BACKGROUND_COLOR; private int mProgressColor = DEFAULT_PROGRESS_COLOR; //进度条的每格线宽,间距,长度 private int dashWith = 4; private int dashSpace = 6; private int lineWidth = 60; //最外圈线的宽度和与进度条之间的间距 private int outLineWidth = 5; private int gapWidth = 25; //指针的线宽度, 半径, 以及指针与进度条的间距 private int pointLineWidth = 10; private int pointRadius = 25; private int pointGap = 20; private int mProgress = 0; //外线 private RectF mOuterRectF; private Paint mOuterPaint; //进度条 private RectF mRectF; private Paint mPaint; private Paint mProgressPaint; //指针 private Paint mInnerCirclePaint; private Paint mPointerPaint; private Path mPointerPath; private float centerX; private float centerY; private ValueAnimator animator; private OnProgressChangeListener mListener; public GradeProgressView(Context context) { this(context, null); } public GradeProgressView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public GradeProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setup(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public GradeProgressView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } private void setup() { mRectF = new RectF(); mOuterRectF = new RectF(); mOuterPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mOuterPaint.setStrokeWidth(outLineWidth); mOuterPaint.setColor(mBackgroundColor); mOuterPaint.setStyle(Paint.Style.STROKE); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStrokeWidth(lineWidth); mPaint.setColor(mBackgroundColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setPathEffect(new DashPathEffect(new float[]{dashWith, dashSpace}, dashSpace)); mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mProgressPaint.setStrokeWidth(lineWidth); mProgressPaint.setColor(mProgressColor); mProgressPaint.setStyle(Paint.Style.STROKE); mProgressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith, dashSpace}, dashSpace)); mPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPointerPaint.setStrokeWidth(pointLineWidth / 2); mPointerPaint.setColor(mProgressColor); mPointerPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPointerPaint.setStrokeCap(Paint.Cap.ROUND); mPointerPaint.setShadowLayer(4, 3, 0, 0x20000000); mInnerCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mInnerCirclePaint.setStrokeWidth(pointLineWidth); mInnerCirclePaint.setColor(mProgressColor); mInnerCirclePaint.setStyle(Paint.Style.STROKE); mInnerCirclePaint.setShadowLayer(4, 3, 0, 0x20000000); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int value = outLineWidth / 2; mOuterRectF.set(value, value, w - value, h - value); int gap = lineWidth / 2 + outLineWidth + gapWidth; mRectF.set(mOuterRectF.left + gap, mOuterRectF.top + gap, mOuterRectF.right - gap, mOuterRectF.bottom - gap); centerX = mRectF.centerX(); centerY = mRectF.centerY(); mPointerPath = new Path(); mPointerPath.moveTo(centerX + pointRadius, centerY - 7); mPointerPath.lineTo(centerX + pointRadius, centerY + 7); mPointerPath.lineTo(mRectF.right - pointGap - lineWidth / 2, centerY); mPointerPath.lineTo(centerX + pointRadius, centerY - 7); mPointerPath.close(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float degree = 2.7f * mProgress; //draw out arc canvas.drawArc(mOuterRectF, 135, 270, false, mOuterPaint); //draw background arc canvas.drawArc(mRectF, 135 + degree, 270 - degree, false, mPaint); //draw progress arc canvas.drawArc(mRectF, 135, degree, false, mProgressPaint); //draw pointer canvas.drawCircle(centerX, centerY, pointRadius, mInnerCirclePaint); canvas.save(); canvas.rotate(135 + degree, centerX, centerY); canvas.drawPath(mPointerPath, mPointerPaint); canvas.restore(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int measureWidth = MeasureSpec.getSize(widthMeasureSpec); int measureHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(Math.min(measureHeight, measureWidth), Math.min(measureHeight, measureWidth)); } public void setOnProgressChangeListener(OnProgressChangeListener listener){ this.mListener = listener; } public int getProgressColor() { return mProgressColor; } public void setProgressColor(int progressColor) { this.mProgressColor = progressColor; if(mProgressPaint != null){ mProgressPaint.setColor(mProgressColor); } if(mPointerPaint != null){ mPointerPaint.setColor(mProgressColor); } if(mInnerCirclePaint != null){ mInnerCirclePaint.setColor(mProgressColor); } postInvalidate(); } public int getBackgroundColor() { return mBackgroundColor; } public void setBackgroundColor(int backgroundColor) { this.mBackgroundColor = backgroundColor; if(mPaint != null){ mPaint.setColor(mBackgroundColor); } if(mOuterPaint != null){ mOuterPaint.setColor(mBackgroundColor); } postInvalidate(); } public int getLineWidth() { return lineWidth; } public void setLineWidth(int lineWidth) { this.lineWidth = lineWidth; if(mPaint != null){ mPaint.setStrokeWidth(lineWidth); } if(mProgressPaint != null){ mProgressPaint.setStrokeWidth(lineWidth); } postInvalidate(); } public int getOutLineWidth() { return outLineWidth; } public void setOutLineWidth(int outLineWidth) { this.outLineWidth = outLineWidth; if(mOuterPaint != null){ mOuterPaint.setStrokeWidth(outLineWidth); } postInvalidate(); } public int getGapWidth() { return gapWidth; } public void setGapWidth(int gapWidth) { this.gapWidth = gapWidth; } public int getProgress() { return mProgress; } public void setProgress(@IntRange(from = 0, to = 100) int progress) { if(progress > 100){ progress = 100; } if(progress < 0){ progress = 0; } this.mProgress = progress; if(mListener != null){ mListener.onProgressChanged(GradeProgressView.this, mProgress); } postInvalidate(); } public void setProgressWidthAnimation(@IntRange(from = 0, to = 100) int progress){ if(progress > 100){ progress = 100; } if(progress < 0){ progress = 0; } if(animator != null && animator.isRunning()){ animator.cancel(); animator = null; } animator = ValueAnimator.ofInt(mProgress, progress); int duration = 10 * Math.abs(progress - mProgress); animator.setDuration(duration); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int value = (int)valueAnimator.getAnimatedValue(); if(mProgress != value) { mProgress = value; if(mListener != null){ mListener.onProgressChanged(GradeProgressView.this, mProgress); } postInvalidate(); } } }); animator.start(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if(animator != null){ animator.cancel(); animator = null; } } public interface OnProgressChangeListener{ void onProgressChanged(GradeProgressView gradeProgressView, int progress); } }

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

时间: 2024-10-16 08:24:35

Android仿小米安全中心检测进度条效果的相关文章

Android仿小米安全中心检测进度条效果_Android

模仿小米安全中心检测效果 废话少说,咱们先上效果图: github地址: https://github.com/niniloveyou/GradeProgressView 这个效果的使用场景并不多,主要是各种检测的时候,比如垃圾清理,手机安全检测, 当然如果你不嫌弃这个效果丑, 也可以用作进度条.哈哈. 下面说点干货分析下这个效果怎么实现: 拿到这个效果首先想想主要有哪些技术难点: 1.进度条 2.中间的指针怎么弄 1.进度条 有人说进度条还不容易吗? 就这样写: mPaint.setPathE

Android仿水波纹流量球进度条控制器_Android

仿水波纹流球进度条控制器,Android实现高端大气的主流特效,供大家参考,具体内容如下 效果图: CircleView 这里主要是实现中心圆以及水波特效 package com.lgl.circleview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.gra

Android仿水波纹流量球进度条控制器

仿水波纹流球进度条控制器,Android实现高端大气的主流特效,供大家参考,具体内容如下 效果图: CircleView 这里主要是实现中心圆以及水波特效 package com.lgl.circleview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.gra

小米视频加载进度条效果实现

原文:小米视频加载进度条效果实现 好吧,其实这些都是我闲暇时自己做着玩的,以前总是拿来主义,现在分享一下让我也为大家做一点贡献好了.废话不说了,看效果. 好吧 其实没什么技术含量 直接上代码好了 和我上一篇利用WPF动画实现圆形进度条是一个道理,表现形式不同而已. 1 <UserControl x:Class="MyUserControlLibrary.CircleProgressbarcontrol" 2 xmlns="http://schemas.microsoft

Android开发之模仿微信打开网页的进度条效果(高仿)_Android

一,为什么说是真正的高仿? 阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果. 好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是

Android开发之模仿微信打开网页的进度条效果(高仿)

一,为什么说是真正的高仿? 阐述这个问题前,先说下之前网上的,各位可以复制这段字,去百度一下  "仿微信打开网页的进度条效果" ,你会看到有很多类似的文章,不过他们有个共同点,就是实现方法都是一样的,而且,都忽略了微信加载网页时,进度条的缓慢动画效果,它不是生硬地一滑而过,而是用户体验很好,有个速度的变化,由慢到快的效果,语言难于描述,相信各位都有下载微信,可以随便打开个公众号的文章看看效果. 好了,上面说到,之前网上的方法都是都忽略了微信加载网页时,进度条的缓慢动画效果,实现代码也是

Android特效专辑(十一)——仿水波纹流量球进度条控制器,实现高端大气的主流特效

Android特效专辑(十一)--仿水波纹流球进度条控制器,实现高端大气的主流特效 今天看到一个效果挺不错的,就模仿了下来,加上了一些自己想要的效果,感觉还不错的样子,所以就分享出来了,话不多说,上图 截图 CircleView 这里主要是实现中心圆以及水波特效 package com.lgl.circleview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Co

Android自定义View仿华为圆形加载进度条

View仿华为圆形加载进度条效果图 实现思路 可以看出该View可分为三个部分来实现 最外围的圆,该部分需要区分进度圆和底部的刻度圆,进度部分的刻度需要和底色刻度区分开来 中间显示的文字进度,需要让文字在View中居中显示 旋转的小圆点,小圆点需要模拟小球下落运动时的加速度效果,开始下落的时候慢,到最底部时最快,上来时速度再逐渐减慢 具体实现 先具体细分讲解,博客最后面给出全部源码 (1)首先为View创建自定义的xml属性 在工程的values目录下新建attrs.xml文件 <resourc

Android编程实现类似于圆形ProgressBar的进度条效果

本文实例讲述了Android编程实现类似于圆形ProgressBar的进度条效果.分享给大家供大家参考,具体如下: 我们要实现一个类似于小米分享中的圆形播放进度条,android自带的圆形ProgressBar是默认自动旋转的,所以无法实现,于是我们想到了使用自定义一个View,来实现这种效果. 首先来看看自己定义的View package cn.easymobi.application.bell.common; import android.content.Context; import an