欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-03-04 15:06:17
模仿小米安全中心检测效果 废话少说,咱们先上效果图: github地址: https://github.com/niniloveyou/gradeprogressvie...

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

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

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

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

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

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

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

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);
 }
}

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