Android仿小米安全中心检测进度条效果
程序员文章站
2024-03-04 15:06:17
模仿小米安全中心检测效果
废话少说,咱们先上效果图:
github地址: https://github.com/niniloveyou/gradeprogressvie...
模仿小米安全中心检测效果
废话少说,咱们先上效果图:
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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。