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

Android常用进度条效果分享

程序员文章站 2024-03-03 23:36:46
先看看效果: activity_main.xml主页布局就2个button,分别弹出不同效果的2个进度条

先看看效果:

Android常用进度条效果分享

activity_main.xml主页布局就2个button,分别弹出不同效果的2个进度条

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="com.example.dialog.mainactivity" >
 <button
  android:id="@+id/button1"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="@string/hello_world" />
  <button
  android:id="@+id/button2"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="@string/hello_world" />
</linearlayout>

mainactivity

package com.example.dialog;
import android.os.bundle;
import android.support.v4.app.fragmentactivity;
import android.view.view;
public class mainactivity extends fragmentactivity {
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  findviewbyid(r.id.button1).setonclicklistener(
    new view.onclicklistener() {
     @override
     public void onclick(view v) {
      myloaddialog myloaddialog = new myloaddialog(
        mainactivity.this, 1);
      myloaddialog.show();
     }
    });

  findviewbyid(r.id.button2).setonclicklistener(
    new view.onclicklistener() {
     @override
     public void onclick(view v) {
      myloaddialog myloaddialog = new myloaddialog(
        mainactivity.this, 2);
      myloaddialog.show();
     }
    });
 }
}

myloaddialog

package com.example.dialog;

import android.app.dialog;
import android.content.context;
import android.graphics.color;
import android.view.view;
import android.widget.imageview;
import android.widget.textview;

public class myloaddialog extends dialog{

 public myloaddialog(context context,int args) {
   super(context, r.style.perfectdialog); 
   init(args);
 }
  private int barcolor = color.parsecolor("#ff009688");

  private void init(int args) { 
   if (args == 1) {
   view contentview = view.inflate(getcontext(),
     r.layout.dialog_load_classic_layout, null);
   setcontentview(contentview);
   loadclassicview loadclassicview = (loadclassicview) contentview
     .findviewbyid(r.id.dialogloadview);
   loadclassicview.startload();
  }else if (args == 2) {

   view contentview = view.inflate(getcontext(),
     r.layout.dialog_load_material_layout, null);
   setcontentview(contentview);



    loadmaterialview progresswheel = (loadmaterialview) contentview.findviewbyid(r.id.dialogloadview);
    progresswheel.setbarcolor(barcolor);
    progresswheel.spin();
  }

  } 
}

 </style>


  <style name="perfectdialog" parent="@android:style/theme.dialog">
  <item name="android:windowisfloating">true</item>//是否浮现在activity之上
  <item name="android:windowistranslucent">false</item>//是否半透明
  <item name="android:windownotitle">true</item>//是否显示title标题
  <item name="android:windowframe">@null</item>//设置windowframe框
  <item name="android:windowfullscreen">false</item>//是否全屏显示
  <item name="android:windowbackground">@android:color/transparent</item>//设置dialog的背景
  <item name="android:windowanimationstyle">@style/dialoganims</item>//设置窗口动画效果
  <item name="android:backgrounddimenabled">true</item>//背景是否变暗
  <item name="android:backgrounddimamount">0.5</item>//设置背景变暗程度
  <item name="android:windowcloseontouchoutside">false</item>
  <item name="android:background">@android:color/transparent</item>
 </style>

  <style name="dialoganims">
  <item name="android:windowenteranimation">@anim/enter</item>//进入动画
  <item name="android:windowexitanimation">@anim/exit</item>//退出动画
 </style>

enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha
  android:duration="90"
  android:fromalpha="0"
  android:toalpha="1"/>
 <scale
  android:duration="135"
  android:fromxscale="0.8"
  android:toxscale="1.05"
  android:fromyscale="0.8"
  android:toyscale="1.05"
  android:pivotx="50%"
  android:pivoty="50%"/>
 <scale
  android:duration="105"
  android:fromxscale="1.05"
  android:toxscale="0.95"
  android:fromyscale="1.05"
  android:toyscale="0.95"
  android:startoffset="135"
  android:pivotx="50%"
  android:pivoty="50%"/>
 <scale
  android:duration="135"
  android:fromxscale="0.95"
  android:toxscale="1"
  android:fromyscale="0.95"
  android:toyscale="1"
  android:startoffset="240"
  android:pivotx="50%"
  android:pivoty="50%"/>
</set>

exit.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha
  android:duration="200"
  android:fromalpha="1"
  android:toalpha="0"/>
 <scale
  android:duration="200"
  android:fromxscale="1"
  android:toxscale="0.1"
  android:fromyscale="1"
  android:toyscale="0.1"
  android:pivotx="50%"
  android:pivoty="50%"/>
</set>

  首先看带第一个效果图的布局文件
dialog_load_classic_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="@drawable/background_round_corner"
 android:padding="35dp">

 <com.example.dialog.loadclassicview
  android:id="@+id/dialogloadview"
  android:layout_width="45dp"
  android:layout_height="45dp" />

</linearlayout>

背景圆角background_round_corner.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle">
 <corners android:radius="8dp"/>
 <solid android:color="#ffffff"/>
</shape>

loadclassicview

package com.example.dialog;

import android.animation.argbevaluator;
import android.content.context;
import android.content.res.resources;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.util.attributeset;
import android.util.displaymetrics;
import android.util.typedvalue;
import android.view.view;

/**
 * created by dandy on 2016/5/31.
 */
public class loadclassicview extends view {

 private static final string tag = "loadingview";

 private static final long delay_duration = 65;

 private static final float size = 22f;//默认大小

 private static final float raidus = 18f;//内部圆半径

 private static final int start_color = color.parsecolor("#5a5a5a");//起始颜色

 private static final int end_color = color.parsecolor("#dddddd");//结束颜色

 private static final int count = 12;//默认加载条个数

 private static final float stroke_width = 6.0f;//加载条粗值

 private float size = size;

 private float radius = raidus;

 private int startcolor = start_color;

 private int endcolor = end_color;

 private int count = count;

 private float strokewidth = stroke_width;

 private displaymetrics dm;

 private argbevaluator colorevaluator;

 private int [] colors;//加载条颜色

 private loadingline [] loadinglines;//加载条集合

 private paint paint;

 private double startangle = 0;

 private int exactlysize;

 private int startindex = 0;

 /**
  * 构造方法
  * @param context
  */
 public loadclassicview(context context){
  this(context, null);
 }

 public loadclassicview(context context, attributeset attributeset){
  super(context, attributeset);
  setupinit(attributeset);
 }

 private void setupinit(attributeset set){
  dm = resources.getsystem().getdisplaymetrics();
  paint = new paint();
  paint.setantialias(true);
  paint.setstrokewidth(strokewidth);
  paint.setstrokecap(paint.cap.round);
  initcolor();
  initloadinglines();
 }

 /*
  * 初始化每个的颜色
  */
 private void initcolor(){
  colorevaluator = new argbevaluator();
  colors = new int[count];
  for(int i = 0;i < count;i++){
   colors[i] = (integer)colorevaluator.evaluate(i*1.0f/(count-1),startcolor,endcolor);

  }
 }

 /**
  * 为每个赋值颜色值
  */
 private void initloadinglines(){
  loadinglines = new loadingline[count];
  for(int i = 0;i <count;i++){
   loadingline loadingline = new loadingline();
   loadingline.drawcolor = colors[i];
   loadinglines[i] = loadingline;
  }
 }

 /**
  * 设置显示颜色
  * @param index,线段颜色初始化位置
  */
 private void setcolor(int index){
  int lineindex;
  for(int i = 0;i < count;i++){
   lineindex = index + i;
   loadinglines[lineindex >= count?lineindex - count:lineindex].drawcolor = colors[i];
  }
 }


 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  /**计算宽**/
  final int widthmode = measurespec.getmode(widthmeasurespec);
  int width = measurespec.getsize(widthmeasurespec);
  if(widthmode == measurespec.unspecified || widthmode == measurespec.at_most){
   width = applydimension(size);
  }

  /**计算高**/
  final int heightmode = measurespec.getmode(heightmeasurespec);
  int height = measurespec.getsize(heightmeasurespec);
  if (heightmode == measurespec.unspecified || heightmode == measurespec.at_most) {
   height = applydimension(size);
  }

  /**
   * 取小的值作为控件的大小
   */
  exactlysize = width >= height ? height:width;

  this.radius = 0.22f * exactlysize;

  setmeasureddimension(exactlysize,exactlysize);

 }

 @override
 protected void onlayout(boolean changed, int left, int top, int right, int bottom) {
  float delayangle = 360.0f / count;
  loadingline loadingline;
  double value;
  for(int i = 0;i < count;i++){
   loadingline = loadinglines[i];
   value = startangle * math.pi / 180;
   loadingline.startx = (int) math.round(radius * math.cos(value));
   loadingline.starty = (int) math.round(radius * math.sin(value));
   loadingline.endx = (int) math.round(exactlysize / 2.5f * math.cos(value));
   loadingline.endy = (int) math.round(exactlysize / 2.5f * math.sin(value));
   startangle += delayangle;
  }
  startangle = 0;
 }

 @override
 protected void ondraw(canvas canvas) {
  canvas.save();
  canvas.translate(exactlysize/2.0f,exactlysize/2.0f);
  for(int i = 0; i < count;i++){
   loadingline loadingline = loadinglines[i];
   paint.setcolor(loadingline.drawcolor);
   canvas.drawline(loadingline.startx, loadingline.starty, loadingline.endx, loadingline.endy, paint);
  }
  canvas.restore();
 }

 public void startload(){
  postdelayed(runnable,100);
 }

 public void finishload(){
  removecallbacks(runnable);
 }

 private runnable runnable = new runnable() {
  @override
  public void run() {
   postinvalidate();
   removecallbacks(runnable);
   setcolor(startindex % count);
   startindex++;
   postdelayed(runnable,delay_duration);
  }
 };

 /**
  * px2dp
  * @param value
  */
 private int applydimension(float value){
  return (int) typedvalue.applydimension(typedvalue.complex_unit_dip, value, dm);
 }

 private static class loadingline{
  private int drawcolor;
  private int startx;
  private int starty;
  private int endx;
  private int endy;
 }
}

接下来看第二个图片
dialog_load_material_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:orientation="vertical"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="@drawable/background_round_corner"
 android:padding="35dp">
 <com.example.dialog.loadmaterialview
  android:id="@id/dialogloadview"
  android:layout_width="45dp"
  android:layout_height="45dp" />
</linearlayout>

loadmaterialview

package com.example.dialog;

/**
 * created by seeker on 2016/8/4.
 *
 * @copy https://github.com/pnikosis/materialish-progress
 */

import android.annotation.targetapi;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.paint.style;
import android.graphics.rectf;
import android.os.build;
import android.os.parcel;
import android.os.parcelable;
import android.os.systemclock;
import android.provider.settings;
import android.util.attributeset;
import android.util.displaymetrics;
import android.util.typedvalue;
import android.view.view;



public class loadmaterialview extends view {

 private static final string tag = "progresswheel";

 private final int barlength = 16;
 private final int barmaxlength = 270;
 private final long pausegrowingtime = 200;
 /**
  * *********
  * defaults *
  * **********
  */
 //sizes (with defaults in dp)
 private int circleradius = 28;
 private int barwidth = 4;
 private int rimwidth = 4;
 private boolean fillradius = false;
 private double timestartgrowing = 0;
 private double barspincycletime = 460;
 private float barextralength = 0;
 private boolean bargrowingfromfront = true;
 private long pausedtimewithoutgrowing = 0;
 //colors (with defaults)
 private int barcolor = 0xaa000000;
 private int rimcolor = 0x00ffffff;

 //paints
 private paint barpaint = new paint();
 private paint rimpaint = new paint();

 //rectangles
 private rectf circlebounds = new rectf();

 //animation
 //the amount of degrees per second
 private float spinspeed = 230.0f;
 //private float spinspeed = 120.0f;
 // the last time the spinner was animated
 private long lasttimeanimated = 0;

 private boolean linearprogress;

 private float mprogress = 0.0f;
 private float mtargetprogress = 0.0f;
 private boolean isspinning = false;

 private progresscallback callback;

 private boolean shouldanimate;

 /**
  * the constructor for the progresswheel
  */
 public loadmaterialview(context context, attributeset attrs) {
  super(context, attrs);

  parseattributes(context.obtainstyledattributes(attrs, r.styleable.loadmaterialview));

  setanimationenabled();
 }

 /**
  * the constructor for the progresswheel
  */
 public loadmaterialview(context context) {
  super(context);
  setanimationenabled();
 }

 @targetapi(build.version_codes.jelly_bean_mr1)
 private void setanimationenabled() {
  int currentapiversion = build.version.sdk_int;

  float animationvalue;
  if (currentapiversion >= build.version_codes.jelly_bean_mr1) {
   animationvalue = settings.global.getfloat(getcontext().getcontentresolver(),
     settings.global.animator_duration_scale, 1);
  } else {
   animationvalue = settings.system.getfloat(getcontext().getcontentresolver(),
     settings.system.animator_duration_scale, 1);
  }

  shouldanimate = animationvalue != 0;
 }

 //----------------------------------
 //setting up stuff
 //----------------------------------

 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure(widthmeasurespec, heightmeasurespec);

  int viewwidth = circleradius + this.getpaddingleft() + this.getpaddingright();
  int viewheight = circleradius + this.getpaddingtop() + this.getpaddingbottom();

  int widthmode = measurespec.getmode(widthmeasurespec);
  int widthsize = measurespec.getsize(widthmeasurespec);
  int heightmode = measurespec.getmode(heightmeasurespec);
  int heightsize = measurespec.getsize(heightmeasurespec);

  int width;
  int height;

  //measure width
  if (widthmode == measurespec.exactly) {
   //must be this size
   width = widthsize;
  } else if (widthmode == measurespec.at_most) {
   //can't be bigger than...
   width = math.min(viewwidth, widthsize);
  } else {
   //be whatever you want
   width = viewwidth;
  }

  //measure height
  if (heightmode == measurespec.exactly || widthmode == measurespec.exactly) {
   //must be this size
   height = heightsize;
  } else if (heightmode == measurespec.at_most) {
   //can't be bigger than...
   height = math.min(viewheight, heightsize);
  } else {
   //be whatever you want
   height = viewheight;
  }

  setmeasureddimension(width, height);
 }

 /**
  * use onsizechanged instead of onattachedtowindow to get the dimensions of the view,
  * because this method is called after measuring the dimensions of match_parent & wrap_content.
  * use this dimensions to setup the bounds and paints.
  */
 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
  super.onsizechanged(w, h, oldw, oldh);

  setupbounds(w, h);
  setuppaints();
  invalidate();
 }

 /**
  * set the properties of the paints we're using to
  * draw the progress wheel
  */
 private void setuppaints() {
  barpaint.setcolor(barcolor);
  barpaint.setantialias(true);
  barpaint.setstyle(style.stroke);
  barpaint.setstrokewidth(barwidth);

  rimpaint.setcolor(rimcolor);
  rimpaint.setantialias(true);
  rimpaint.setstyle(style.stroke);
  rimpaint.setstrokewidth(rimwidth);
 }

 /**
  * set the bounds of the component
  */
 private void setupbounds(int layout_width, int layout_height) {
  int paddingtop = getpaddingtop();
  int paddingbottom = getpaddingbottom();
  int paddingleft = getpaddingleft();
  int paddingright = getpaddingright();

  if (!fillradius) {
   // width should equal to height, find the min value to setup the circle
   int minvalue = math.min(layout_width - paddingleft - paddingright,
     layout_height - paddingbottom - paddingtop);

   int circlediameter = math.min(minvalue, circleradius * 2 - barwidth * 2);

   // calc the offset if needed for centering the wheel in the available space
   int xoffset = (layout_width - paddingleft - paddingright - circlediameter) / 2 + paddingleft;
   int yoffset = (layout_height - paddingtop - paddingbottom - circlediameter) / 2 + paddingtop;

   circlebounds =
     new rectf(xoffset + barwidth, yoffset + barwidth, xoffset + circlediameter - barwidth,
       yoffset + circlediameter - barwidth);
  } else {
   circlebounds = new rectf(paddingleft + barwidth, paddingtop + barwidth,
     layout_width - paddingright - barwidth, layout_height - paddingbottom - barwidth);
  }
 }

 /**
  * parse the attributes passed to the view from the xml
  *
  * @param a the attributes to parse
  */
 private void parseattributes(typedarray a) {
  // we transform the default values from dip to pixels
  displaymetrics metrics = getcontext().getresources().getdisplaymetrics();
  barwidth = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, barwidth, metrics);
  rimwidth = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, rimwidth, metrics);
  circleradius =
    (int) typedvalue.applydimension(typedvalue.complex_unit_dip, circleradius, metrics);

  circleradius =
    (int) a.getdimension(r.styleable.loadmaterialview_matprog_circleradius, circleradius);

  fillradius = a.getboolean(r.styleable.loadmaterialview_matprog_fillradius, false);

  barwidth = (int) a.getdimension(r.styleable.loadmaterialview_matprog_barwidth, barwidth);

  rimwidth = (int) a.getdimension(r.styleable.loadmaterialview_matprog_rimwidth, rimwidth);

  float basespinspeed =
    a.getfloat(r.styleable.loadmaterialview_matprog_spinspeed, spinspeed / 360.0f);
  spinspeed = basespinspeed * 360;

  barspincycletime =
    a.getint(r.styleable.loadmaterialview_matprog_barspincycletime, (int) barspincycletime);

  barcolor = a.getcolor(r.styleable.loadmaterialview_matprog_barcolor, barcolor);

  rimcolor = a.getcolor(r.styleable.loadmaterialview_matprog_rimcolor, rimcolor);

  linearprogress = a.getboolean(r.styleable.loadmaterialview_matprog_linearprogress, false);

  if (a.getboolean(r.styleable.loadmaterialview_matprog_progressindeterminate, false)) {
   spin();
  }

  // recycle
  a.recycle();
 }

 public void setcallback(progresscallback progresscallback) {
  callback = progresscallback;

  if (!isspinning) {
   runcallback();
  }
 }

 //----------------------------------
 //animation stuff
 //----------------------------------

 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);

  canvas.drawarc(circlebounds, 360, 360, false, rimpaint);

  boolean mustinvalidate = false;

  if (!shouldanimate) {
   return;
  }

  if (isspinning) {
   //draw the spinning bar
   mustinvalidate = true;

   long deltatime = (systemclock.uptimemillis() - lasttimeanimated);
   float deltanormalized = deltatime * spinspeed / 1000.0f;

   updatebarlength(deltatime);

   mprogress += deltanormalized;
   if (mprogress > 360) {
    mprogress -= 360f;

    // a full turn has been completed
    // we run the callback with -1 in case we want to
    // do something, like changing the color
    runcallback(-1.0f);
   }
   lasttimeanimated = systemclock.uptimemillis();

   float from = mprogress - 90;
   float length = barlength + barextralength;

   if (isineditmode()) {
    from = 0;
    length = 135;
   }

   canvas.drawarc(circlebounds, from, length, false, barpaint);
  } else {
   float oldprogress = mprogress;

   if (mprogress != mtargetprogress) {
    //we smoothly increase the progress bar
    mustinvalidate = true;

    float deltatime = (float) (systemclock.uptimemillis() - lasttimeanimated) / 1000;
    float deltanormalized = deltatime * spinspeed;

    mprogress = math.min(mprogress + deltanormalized, mtargetprogress);
    lasttimeanimated = systemclock.uptimemillis();
   }

   if (oldprogress != mprogress) {
    runcallback();
   }

   float offset = 0.0f;
   float progress = mprogress;
   if (!linearprogress) {
    float factor = 2.0f;
    offset = (float) (1.0f - math.pow(1.0f - mprogress / 360.0f, 2.0f * factor)) * 360.0f;
    progress = (float) (1.0f - math.pow(1.0f - mprogress / 360.0f, factor)) * 360.0f;
   }

   if (isineditmode()) {
    progress = 360;
   }

   canvas.drawarc(circlebounds, offset - 90, progress, false, barpaint);
  }

  if (mustinvalidate) {
   invalidate();
  }
 }

 @override
 protected void onvisibilitychanged(view changedview, int visibility) {
  super.onvisibilitychanged(changedview, visibility);

  if (visibility == visible) {
   lasttimeanimated = systemclock.uptimemillis();
  }
 }

 private void updatebarlength(long deltatimeinmilliseconds) {
  if (pausedtimewithoutgrowing >= pausegrowingtime) {
   timestartgrowing += deltatimeinmilliseconds;

   if (timestartgrowing > barspincycletime) {
    // we completed a size change cycle
    // (growing or shrinking)
    timestartgrowing -= barspincycletime;
    //if(bargrowingfromfront) {
    pausedtimewithoutgrowing = 0;
    //}
    bargrowingfromfront = !bargrowingfromfront;
   }

   float distance =
     (float) math.cos((timestartgrowing / barspincycletime + 1) * math.pi) / 2 + 0.5f;
   float destlength = (barmaxlength - barlength);

   if (bargrowingfromfront) {
    barextralength = distance * destlength;
   } else {
    float newlength = destlength * (1 - distance);
    mprogress += (barextralength - newlength);
    barextralength = newlength;
   }
  } else {
   pausedtimewithoutgrowing += deltatimeinmilliseconds;
  }
 }

 /**
  * check if the wheel is currently spinning
  */

 public boolean isspinning() {
  return isspinning;
 }

 /**
  * reset the count (in increment mode)
  */
 public void resetcount() {
  mprogress = 0.0f;
  mtargetprogress = 0.0f;
  invalidate();
 }

 /**
  * turn off spin mode
  */
 public void stopspinning() {
  isspinning = false;
  mprogress = 0.0f;
  mtargetprogress = 0.0f;
  invalidate();
 }

 /**
  * puts the view on spin mode
  */
 public void spin() {
  lasttimeanimated = systemclock.uptimemillis();
  isspinning = true;
  invalidate();
 }

 private void runcallback(float value) {
  if (callback != null) {
   callback.onprogressupdate(value);
  }
 }

 private void runcallback() {
  if (callback != null) {
   float normalizedprogress = (float) math.round(mprogress * 100 / 360.0f) / 100;
   callback.onprogressupdate(normalizedprogress);
  }
 }

 /**
  * set the progress to a specific value,
  * the bar will be set instantly to that value
  *
  * @param progress the progress between 0 and 1
  */
 public void setinstantprogress(float progress) {
  if (isspinning) {
   mprogress = 0.0f;
   isspinning = false;
  }

  if (progress > 1.0f) {
   progress -= 1.0f;
  } else if (progress < 0) {
   progress = 0;
  }

  if (progress == mtargetprogress) {
   return;
  }

  mtargetprogress = math.min(progress * 360.0f, 360.0f);
  mprogress = mtargetprogress;
  lasttimeanimated = systemclock.uptimemillis();
  invalidate();
 }

 // great way to save a view's state http://*.com/a/7089687/1991053
 @override
 public parcelable onsaveinstancestate() {
  parcelable superstate = super.onsaveinstancestate();

  wheelsavedstate ss = new wheelsavedstate(superstate);

  // we save everything that can be changed at runtime
  ss.mprogress = this.mprogress;
  ss.mtargetprogress = this.mtargetprogress;
  ss.isspinning = this.isspinning;
  ss.spinspeed = this.spinspeed;
  ss.barwidth = this.barwidth;
  ss.barcolor = this.barcolor;
  ss.rimwidth = this.rimwidth;
  ss.rimcolor = this.rimcolor;
  ss.circleradius = this.circleradius;
  ss.linearprogress = this.linearprogress;
  ss.fillradius = this.fillradius;

  return ss;
 }

 @override
 public void onrestoreinstancestate(parcelable state) {
  if (!(state instanceof wheelsavedstate)) {
   super.onrestoreinstancestate(state);
   return;
  }

  wheelsavedstate ss = (wheelsavedstate) state;
  super.onrestoreinstancestate(ss.getsuperstate());

  this.mprogress = ss.mprogress;
  this.mtargetprogress = ss.mtargetprogress;
  this.isspinning = ss.isspinning;
  this.spinspeed = ss.spinspeed;
  this.barwidth = ss.barwidth;
  this.barcolor = ss.barcolor;
  this.rimwidth = ss.rimwidth;
  this.rimcolor = ss.rimcolor;
  this.circleradius = ss.circleradius;
  this.linearprogress = ss.linearprogress;
  this.fillradius = ss.fillradius;

  this.lasttimeanimated = systemclock.uptimemillis();
 }

 /**
  * @return the current progress between 0.0 and 1.0,
  * if the wheel is indeterminate, then the result is -1
  */
 public float getprogress() {
  return isspinning ? -1 : mprogress / 360.0f;
 }

 //----------------------------------
 //getters + setters
 //----------------------------------

 /**
  * set the progress to a specific value,
  * the bar will smoothly animate until that value
  *
  * @param progress the progress between 0 and 1
  */
 public void setprogress(float progress) {
  if (isspinning) {
   mprogress = 0.0f;
   isspinning = false;

   runcallback();
  }

  if (progress > 1.0f) {
   progress -= 1.0f;
  } else if (progress < 0) {
   progress = 0;
  }

  if (progress == mtargetprogress) {
   return;
  }

  // if we are currently in the right position
  // we set again the last time animated so the
  // animation starts smooth from here
  if (mprogress == mtargetprogress) {
   lasttimeanimated = systemclock.uptimemillis();
  }

  mtargetprogress = math.min(progress * 360.0f, 360.0f);

  invalidate();
 }

 /**
  * sets the determinate progress mode
  *
  * @param islinear if the progress should increase linearly
  */
 public void setlinearprogress(boolean islinear) {
  linearprogress = islinear;
  if (!isspinning) {
   invalidate();
  }
 }

 /**
  * @return the radius of the wheel in pixels
  */
 public int getcircleradius() {
  return circleradius;
 }

 /**
  * sets the radius of the wheel
  *
  * @param circleradius the expected radius, in pixels
  */
 public void setcircleradius(int circleradius) {
  this.circleradius = circleradius;
  if (!isspinning) {
   invalidate();
  }
 }

 /**
  * @return the width of the spinning bar
  */
 public int getbarwidth() {
  return barwidth;
 }

 /**
  * sets the width of the spinning bar
  *
  * @param barwidth the spinning bar width in pixels
  */
 public void setbarwidth(int barwidth) {
  this.barwidth = barwidth;
  if (!isspinning) {
   invalidate();
  }
 }

 /**
  * @return the color of the spinning bar
  */
 public int getbarcolor() {
  return barcolor;
 }

 /**
  * sets the color of the spinning bar
  *
  * @param barcolor the spinning bar color
  */
 public void setbarcolor(int barcolor) {
  this.barcolor = barcolor;
  setuppaints();
  if (!isspinning) {
   invalidate();
  }
 }

 /**
  * @return the color of the wheel's contour
  */
 public int getrimcolor() {
  return rimcolor;
 }

 /**
  * sets the color of the wheel's contour
  *
  * @param rimcolor the color for the wheel
  */
 public void setrimcolor(int rimcolor) {
  this.rimcolor = rimcolor;
  setuppaints();
  if (!isspinning) {
   invalidate();
  }
 }

 /**
  * @return the base spinning speed, in full circle turns per second
  * (1.0 equals on full turn in one second), this value also is applied for
  * the smoothness when setting a progress
  */
 public float getspinspeed() {
  return spinspeed / 360.0f;
 }

 /**
  * sets the base spinning speed, in full circle turns per second
  * (1.0 equals on full turn in one second), this value also is applied for
  * the smoothness when setting a progress
  *
  * @param spinspeed the desired base speed in full turns per second
  */
 public void setspinspeed(float spinspeed) {
  this.spinspeed = spinspeed * 360.0f;
 }

 /**
  * @return the width of the wheel's contour in pixels
  */
 public int getrimwidth() {
  return rimwidth;
 }

 /**
  * sets the width of the wheel's contour
  *
  * @param rimwidth the width in pixels
  */
 public void setrimwidth(int rimwidth) {
  this.rimwidth = rimwidth;
  if (!isspinning) {
   invalidate();
  }
 }

 public interface progresscallback {
  /**
   * method to call when the progress reaches a value
   * in order to avoid float precision issues, the progress
   * is rounded to a float with two decimals.
   *
   * in indeterminate mode, the callback is called each time
   * the wheel completes an animation cycle, with, the progress value is -1.0f
   *
   * @param progress a double value between 0.00 and 1.00 both included
   */
  public void onprogressupdate(float progress);
 }

 static class wheelsavedstate extends basesavedstate {
  //required field that makes parcelables from a parcel
  public static final creator<wheelsavedstate> creator =
    new creator<wheelsavedstate>() {
     public wheelsavedstate createfromparcel(parcel in) {
      return new wheelsavedstate(in);
     }

     public wheelsavedstate[] newarray(int size) {
      return new wheelsavedstate[size];
     }
    };
  float mprogress;
  float mtargetprogress;
  boolean isspinning;
  float spinspeed;
  int barwidth;
  int barcolor;
  int rimwidth;
  int rimcolor;
  int circleradius;
  boolean linearprogress;
  boolean fillradius;

  wheelsavedstate(parcelable superstate) {
   super(superstate);
  }

  private wheelsavedstate(parcel in) {
   super(in);
   this.mprogress = in.readfloat();
   this.mtargetprogress = in.readfloat();
   this.isspinning = in.readbyte() != 0;
   this.spinspeed = in.readfloat();
   this.barwidth = in.readint();
   this.barcolor = in.readint();
   this.rimwidth = in.readint();
   this.rimcolor = in.readint();
   this.circleradius = in.readint();
   this.linearprogress = in.readbyte() != 0;
   this.fillradius = in.readbyte() != 0;
  }

  @override
  public void writetoparcel(parcel out, int flags) {
   super.writetoparcel(out, flags);
   out.writefloat(this.mprogress);
   out.writefloat(this.mtargetprogress);
   out.writebyte((byte) (isspinning ? 1 : 0));
   out.writefloat(this.spinspeed);
   out.writeint(this.barwidth);
   out.writeint(this.barcolor);
   out.writeint(this.rimwidth);
   out.writeint(this.rimcolor);
   out.writeint(this.circleradius);
   out.writebyte((byte) (linearprogress ? 1 : 0));
   out.writebyte((byte) (fillradius ? 1 : 0));
  }
 }
}

attrs_loadmaterialview.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="loadmaterialview">
  <attr name="matprog_progressindeterminate" format="boolean" />
  <attr name="matprog_barcolor" format="color" />
  <attr name="matprog_rimcolor" format="color" />
  <attr name="matprog_rimwidth" format="dimension" />
  <attr name="matprog_spinspeed" format="float" />
  <attr name="matprog_barspincycletime" format="integer" />
  <attr name="matprog_circleradius" format="dimension" />
  <attr name="matprog_fillradius" format="boolean" />
  <attr name="matprog_barwidth" format="dimension" />
  <attr name="matprog_linearprogress" format="boolean" />
 </declare-styleable>
</resources>

源码下载:http://xiazai.jb51.net/201610/yuanma/androiddialog(jb51.net).rar

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