前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android自定义View实现加载进度条效果

Android自定义View实现加载进度条效果

作者头像
砸漏
发布2020-11-05 14:44:28
7490
发布2020-11-05 14:44:28
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

上一篇文章总结了下自定义View的几个步骤,如果还有不清楚的同学可以先去看看Android自定义View(一) ,这篇文章和大家分享一下自定义加载进度条,效果如下

下面就以水平的进度条为列进行讲解:

1.首先还是在attrs.xml文件中自定义我们需要的属性:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"? 
<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.获取我们的自定义属性:

代码语言:javascript
复制
/**
 * 字体大小
 */
private int mTextSize;
/**
 * 字体颜色
 */
private int mTextColor;
/**
 * 渐变开始的颜色
 */
private int mStartColor;
/**
 * 渐变结束的颜色
 */
private int mEndColor;
/**
 * 进度条的宽
 */
private int mProgressWidth;
/**
 * 进度条的圆角大小
 */
private int mRadius;
/**
 * 默认进度条的颜色
 */
private int mBgColor;
/**
 * 进度条的当前进度
 */
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:
 /**
  * 默认设置为16sp,TypeValue也可以把sp转化为px
  */
 mTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
 break;
 case R.styleable.GradientProgressBar_textColor:
 /**
  * 默认设置为黑色
  */
 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()方法做如下操作

代码语言:javascript
复制
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()方法

代码语言:javascript
复制
@Override
protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);

 /**
 * 设置画笔的属性
 */
 mPaint.setColor(mBgColor);
 mPaint.setStyle(Paint.Style.FILL);

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

 /**
 * 设置线性渐变,设置渐变开始的起点坐标和终点坐标,渐变开始和结束的颜色,设置镜像
 * 对于这个方法不太明白的可以google一下,这里不再详细说明
 */
 LinearGradient gradient = new LinearGradient(0, getHeight() / 2, mProgressWidth, getHeight() / 2,
 mStartColor, mEndColor, Shader.TileMode.MIRROR);
 mPaint.setShader(gradient);
 /**
 * 根据进度绘制圆角矩形
 */
 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);
}

好了,这样就完成了我们水平渐变加载进度条,下面贴出圆形进度条的源码:

代码语言:javascript
复制
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:
/**
* 默认设置为16sp,TypeValue也可以把sp转化为px
*/
mTextSize = array.getDimensionPixelSize(index, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
case R.styleable.RoundProgressBar_textColorRound:
/**
* 默认设置为黑色
*/
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);
/**
* 设置画笔的属性
*/
mPaint.setColor(mBgColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mCircleWidth);
/**
* 绘制圆环背景
*/
int xPoint = getWidth() / 2;//获取圆心x的坐标
int radius = xPoint - mCircleWidth;//获取圆心的半径
canvas.drawCircle(xPoint, xPoint, radius, mPaint);//用于定义的圆弧的形状和大小的界限
/**
* 绘制圆环
*/
mPaint.setColor(mCurrentColor);
RectF oval = new RectF(xPoint - radius, xPoint - radius, radius + xPoint, radius + xPoint);
canvas.drawArc(oval, -90, mCurrentProgress, false, mPaint);
/**
* 绘制当前进度文本
*/
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

代码语言:javascript
复制
<?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: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 

好了,这样就完成了我们的水平加载进度条,和圆形加载进度条效果了,是不是感觉还可以啊。

源码下载地址

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档