溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android自定義View如何實現(xiàn)加載進度條效果?

發(fā)布時間:2020-06-23 15:12:57 來源:億速云 閱讀:1351 作者:清晨 欄目:移動開發(fā)

不懂Android自定義View如何實現(xiàn)加載進度條效果??其實想解決這個問題也不難,下面讓小編帶著大家一起學(xué)習(xí)怎么去解決,希望大家閱讀完這篇文章后大所收獲。


效果圖:

Android自定義View如何實現(xiàn)加載進度條效果?

下面就以水平的進度條為列進行講解:

1.首先還是在attrs.xml文件中自定義我們需要的屬性:

<&#63;xml version="1.0" encoding="utf-8"&#63;>
<resources>
 <declare-styleable name="GradientProgressBar">
 <attr name="textSize" format="dimension" />
 <attr name="textColor" format="color" />
 <attr name="bgColor" format="color" />
 <attr name="startColor" format="color" />
 <attr name="endColor" format="color" />
 <attr name="rectRadius" format="dimension" />
 <attr name="loadSpeed" format="integer" />
 <attr name="lineWidth" format="dimension" />
 </declare-styleable>
 <declare-styleable name="RoundProgressBar">
 <attr name="textSizeRound" format="dimension" />
 <attr name="textColorRound" format="color" />
 <attr name="bgColorRound" format="color" />
 <attr name="currentColorRound" format="color" />
 <attr name="circleWidthRound" format="dimension" />
 <attr name="loadSpeedRound" format="integer" />
 </declare-styleable>
</resources>

2.獲取我們的自定義屬性:

/**
 * 字體大小
 */
private int mTextSize;
/**
 * 字體顏色
 */
private int mTextColor;
/**
 * 漸變開始的顏色
 */
private int mStartColor;
/**
 * 漸變結(jié)束的顏色
 */
private int mEndColor;
/**
 * 進度條的寬
 */
private int mProgressWidth;
/**
 * 進度條的圓角大小
 */
private int mRadius;
/**
 * 默認進度條的顏色
 */
private int mBgColor;
/**
 * 進度條的當(dāng)前進度
 */
private float mCurrentProgress;
/**
 * 加載的速度
 */
private int mLoadSpeed;

private String mContent="0%";
private Rect mBounds;
private Paint mPaint;

public GradientProgressBar(Context context) {
 this(context, null);
}

public GradientProgressBar(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
}

public GradientProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GradientProgressBar, defStyleAttr, 0);
 int count = array.getIndexCount();
 for (int i = 0; i < count; i++) {
 int index = array.getIndex(i);
 switch (index) {
 case R.styleable.GradientProgressBar_textSize:
 /**
  * 默認設(shè)置為16sp,TypeValue也可以把sp轉(zhuǎn)化為px
  */
 mTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
 break;
 case R.styleable.GradientProgressBar_textColor:
 /**
  * 默認設(shè)置為黑色
  */
 mTextColor = array.getColor(index, Color.BLACK);
 break;
 case R.styleable.GradientProgressBar_startColor:
 mStartColor = array.getColor(index, Color.BLACK);
 break;
 case R.styleable.GradientProgressBar_endColor:
 mEndColor = array.getColor(index, Color.BLACK);
 break;
 case R.styleable.GradientProgressBar_bgColor:
 mBgColor = array.getColor(index, Color.BLACK);
 break;
 case R.styleable.GradientProgressBar_rectRadius:
 mRadius = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()
 ));
 break;
 case R.styleable.GradientProgressBar_lineWidth:
 mProgressWidth=array.getDimensionPixelSize(index,(int)TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP,200,getResources().getDisplayMetrics()));
 break;
 case R.styleable.GradientProgressBar_loadSpeed:
 mLoadSpeed=array.getInt(index,10);
 break;
 }
 }
 array.recycle();
 init();
}

init()方法做如下操作

private void init(){
 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setAntiAlias(true);
 mBounds = new Rect();
 new Thread(new Runnable() {
 @Override
 public void run() {
 while (mCurrentProgress < mProgressWidth) {
 mCurrentProgress = mCurrentProgress + 1;
 mContent = Math.round((mCurrentProgress / mProgressWidth) * 100) + "%";
 try {
  postInvalidate();
  Thread.sleep(mLoadSpeed);
 } catch (Exception e) {
  e.printStackTrace();
 }
 }
 }
 }).start();
}

3.重寫OnDraw()方法

@Override
protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);

 /**
 * 設(shè)置畫筆的屬性
 */
 mPaint.setColor(mBgColor);
 mPaint.setStyle(Paint.Style.FILL);

 /**
 * 繪制背景圓角矩形
 */
 canvas.drawRoundRect(0, 0, mProgressWidth, getHeight(), mRadius, mRadius, mPaint);

 /**
 * 設(shè)置線性漸變,設(shè)置漸變開始的起點坐標(biāo)和終點坐標(biāo),漸變開始和結(jié)束的顏色,設(shè)置鏡像
 * 對于這個方法不太明白的可以google一下,這里不再詳細說明
 */
 LinearGradient gradient = new LinearGradient(0, getHeight() / 2, mProgressWidth, getHeight() / 2,
 mStartColor, mEndColor, Shader.TileMode.MIRROR);
 mPaint.setShader(gradient);
 /**
 * 根據(jù)進度繪制圓角矩形
 */
 canvas.drawRoundRect(0, 0, mCurrentProgress, getHeight(), mRadius, mRadius, mPaint);

 mPaint.reset();
 mPaint.setAntiAlias(true);
 mPaint.setColor(mTextColor);
 mPaint.setTextSize(mTextSize);

 /**
 * 獲取繪制文本所需的矩形大小
 */
 mPaint.getTextBounds(mContent, 0, mContent.length(), mBounds);
 canvas.drawText(mContent, getWidth() / 2 - mBounds.width() / 2, getHeight() / 2 + mBounds.height() / 2, mPaint);
}

 好了,這樣就完成了我們水平漸變加載進度條,下面貼出圓形進度條的源碼:

public class RoundProgressBar extends View {

 /**
 * 自定義變量
 */
 private int mTextSize;
 private int mTextColor;
 private int mCircleWidth;
 private int mBgColor;
 private int mCurrentColor;
 private int mLoadSpeed;
 private float mCurrentProgress;

 private String mContent = "0%";
 private Rect mBounds;
 private Paint mPaint;

 public RoundProgressBar(Context context) {
 this(context, null);
 }

 public RoundProgressBar(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundProgressBar, defStyleAttr, 0);
 int count = array.getIndexCount();
 for (int i = 0; i < count; i++) {
 int index = array.getIndex(i);
 switch (index) {
 case R.styleable.RoundProgressBar_textSizeRound:
  /**
  * 默認設(shè)置為16sp,TypeValue也可以把sp轉(zhuǎn)化為px
  */
  mTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
  break;
 case R.styleable.RoundProgressBar_textColorRound:
  /**
  * 默認設(shè)置為黑色
  */
  mTextColor = array.getColor(index, Color.BLACK);
  break;
 case R.styleable.RoundProgressBar_bgColorRound:
  mBgColor = array.getColor(index, Color.BLACK);
  break;
 case R.styleable.RoundProgressBar_circleWidthRound:
  mCircleWidth = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()
  ));
  break;
 case R.styleable.RoundProgressBar_currentColorRound:
  mCurrentColor = array.getColor(index, Color.BLACK);
  break;
 case R.styleable.RoundProgressBar_loadSpeedRound:
  mLoadSpeed=array.getInt(index,10);
  break;
 }
 }
 array.recycle();
 init();
 }

 private void init() {
 mBounds = new Rect();
 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setAntiAlias(true);
 new Thread(new Runnable() {
 @Override
 public void run() {
 while (mCurrentProgress < 360) {
  mCurrentProgress = mCurrentProgress + 1;
  mContent = Math.round((mCurrentProgress / 360) * 100) + "%";
  postInvalidate();
  try {
  Thread.sleep(mLoadSpeed);
  } catch (Exception e) {
  e.printStackTrace();
  }
 }
 }
 }).start();
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);

 /**
 * 設(shè)置畫筆的屬性
 */
 mPaint.setColor(mBgColor);
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeWidth(mCircleWidth);

 /**
 * 繪制圓環(huán)背景
 */
 int xPoint = getWidth() / 2;//獲取圓心x的坐標(biāo)
 int radius = xPoint - mCircleWidth;//獲取圓心的半徑
 canvas.drawCircle(xPoint, xPoint, radius, mPaint);//用于定義的圓弧的形狀和大小的界限

 /**
 * 繪制圓環(huán)
 */
 mPaint.setColor(mCurrentColor);
 RectF oval = new RectF(xPoint - radius, xPoint - radius, radius + xPoint, radius + xPoint);
 canvas.drawArc(oval, -90, mCurrentProgress, false, mPaint);

 /**
 * 繪制當(dāng)前進度文本
 */
 mPaint.reset();
 mPaint.setAntiAlias(true);
 mPaint.setColor(mTextColor);
 mPaint.setTextSize(mTextSize);
 mPaint.getTextBounds(mContent, 0, mContent.length(), mBounds);
 canvas.drawText(mContent, xPoint - mBounds.width() / 2, xPoint + mBounds.height() / 2, mPaint);
 }
}

4.在xml文件中申明我們的自定義View

<&#63;xml version="1.0" encoding="utf-8"&#63;>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@android:color/white"
 android:gravity="center_horizontal"
 android:orientation="vertical">
 <com.customeview2.GradientProgressBar
 android:id="@+id/gradientProgressBar"
 android:layout_width="300dp"
 android:layout_height="15dp"
 android:layout_marginLeft="10dp"
 android:layout_marginRight="10dp"
 android:layout_marginTop="200dp"
 app:bgColor="#C3C3C3"
 app:endColor="#25B7FA"
 app:lineWidth="300dp"
 app:loadSpeed="10"
 app:rectRadius="20dp"
 app:startColor="#D2EEFB"
 app:textColor="@android:color/holo_red_light"
 app:textSize="12sp" />

 <com.customeview2.RoundProgressBar
 android:id="@+id/roundProgressBar"
 android:layout_width="60dp"
 android:layout_height="60dp"
 android:layout_below="@+id/gradientProgressBar"
 android:layout_gravity="center"
 android:layout_marginLeft="10dp"
 android:layout_marginRight="10dp"
 android:layout_marginTop="40dp"
 app:bgColorRound="#C3C3C3"
 app:circleWidthRound="3dp"
 app:currentColorRound="#25B7FA"
 app:loadSpeedRound="10"
 app:textColor="@android:color/holo_red_light"
 app:textColorRound="@android:color/holo_red_light"
 app:textSizeRound="11sp" />
</LinearLayout>


感謝你能夠認真閱讀完這篇文章,希望小編分享Android自定義View如何實現(xiàn)加載進度條效果?內(nèi)容對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI