广告
返回顶部
首页 > 资讯 > 移动开发 >Android常用进度条效果分享
  • 788
分享到

Android常用进度条效果分享

进度条Android 2022-06-06 07:06:33 788人浏览 八月长安
摘要

先看看效果: activity_main.xml主页布局就2个button,分别弹出不同效果的2个进度条 <LinearLayout xmlns:Android="H

先看看效果:

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;

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

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;
 
 //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;
 
 public LoadMaterialView(Context context, AttributeSet attrs) {
  super(context, attrs);
  parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.LoadMaterialView));
  setAnimationEnabled();
 }
 
 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);
 }
 
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  setupBounds(w, h);
  setupPaints();
  invalidate();
 }
 
 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);
 }
 
 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);
  }
 }
 
 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;
  }
 }
 
 public boolean isSpinning() {
  return isSpinning;
 }
 
 public void resetCount() {
  mProgress = 0.0f;
  mTargetProgress = 0.0f;
  invalidate();
 }
 
 public void stopSpinning() {
  isSpinning = false;
  mProgress = 0.0f;
  mTargetProgress = 0.0f;
  invalidate();
 }
 
 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);
  }
 }
 
 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://stackoverflow.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();
 }
 
 public float getProgress() {
  return isSpinning ? -1 : mProgress / 360.0f;
 }
 //----------------------------------
 //Getters + setters
 //----------------------------------
 
 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();
 }
 
 public void setLinearProgress(boolean isLinear) {
  linearProgress = isLinear;
  if (!isSpinning) {
   invalidate();
  }
 }
 
 public int getCircleRadius() {
  return circleRadius;
 }
 
 public void setCircleRadius(int circleRadius) {
  this.circleRadius = circleRadius;
  if (!isSpinning) {
   invalidate();
  }
 }
 
 public int getBarWidth() {
  return barWidth;
 }
 
 public void setBarWidth(int barWidth) {
  this.barWidth = barWidth;
  if (!isSpinning) {
   invalidate();
  }
 }
 
 public int getBarColor() {
  return barColor;
 }
 
 public void setBarColor(int barColor) {
  this.barColor = barColor;
  setupPaints();
  if (!isSpinning) {
   invalidate();
  }
 }
 
 public int getRimColor() {
  return rimColor;
 }
 
 public void setRimColor(int rimColor) {
  this.rimColor = rimColor;
  setupPaints();
  if (!isSpinning) {
   invalidate();
  }
 }
 
 public float getSpinSpeed() {
  return spinSpeed / 360.0f;
 }
 
 public void setSpinSpeed(float spinSpeed) {
  this.spinSpeed = spinSpeed * 360.0f;
 }
 
 public int getRimWidth() {
  return rimWidth;
 }
 
 public void setRimWidth(int rimWidth) {
  this.rimWidth = rimWidth;
  if (!isSpinning) {
   invalidate();
  }
 }
 public interface ProgressCallback {
  
  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

您可能感兴趣的文章:Android实现分享功能Android Zxing生成二维码经典案例分享Android登录界面的实现代码分享Android实现第三方授权登录、分享以及获取用户资料Android获取高清app图标代码分享分享一个Android设置圆形图片的特别方法分享Android仿刮奖效果控件Android超实用的Toast提示框优化分享Android 浏览器的开发实例分享android微信支付源码分享分享Android中Toast的自定义使用Android 实现微信,微博,微信朋友圈,QQ分享的功能


--结束END--

本文标题: Android常用进度条效果分享

本文链接: https://www.lsjlt.com/news/23446.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作