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

Android自定义百分数进度条

程序员文章站 2022-06-08 23:53:49
...

上周看到群里有同学谈到自定义进度条的的问题,自己就针对百分数进度条自定义了一个。源码已经传到github上啦,可以下载下来直接能够运行的,也可以直接在里面根据自己的需求进行修改代码!

针对上周有朋友提的建议:上效果图。

这个就是自定义的百分数在进度条上的一个NumberProgressBar,而且在右上角设置了一个取消定时的按钮,便于我们跑一次程序可以多次验证进度条的效果。【不然可能程序运行一次,只能看到一次效果。我建议:大家在写demo的时候也最好采用这样的方式】。 我这里只是为了模拟下进度条的加载效果,所以在运行至100%时,默认的显示了本地中的一张图片。嗯嗯,效果不错,图片效果不错。????????

在这里,说一下主要的逻辑:细节的还是大家自己去github上下载源码研究下。

  1. 自定义进度条的属性:高度,长度,空白区域,百分数,进度条的颜色(已经加载/未加载),最大值,文字颜色,文字大小,文本的宽度,开始绘制,结束绘制等等。

  2. 绘制控件:包括:画笔的初始化,已经加载的画笔,未加载的画笔,文本的画笔。

  3. 设置监听:进度条是自动加载的,所以要设置定时任务,然后设置进度条的监听,时刻进行进度条的刷新。 任务处理的执行。

重点介绍下:

设备旋转时会导致数据的丢失,我们继承了View,好在View给我们 onSaveInstanceState()和onRestoreInstanceState()。

我们就来看下这两个方法,首先这两个方法跟Acticity中的相似方法的主要区别在于Activity是用Bundle进行数据传递的,而View是通过Parcelable进行传递的。如果使用Parcelable对象传递自定义数据就需要实现Parcelable接口和CTRATE静态常量,不但复杂而且代码量很大。但是我们这次是基于RectF作为基础数据,因为RectF是Android提供的并且已经实现了Parcelable接口和CTRATE静态常量,这就很方便啦。 在onSaveInstanceState()方法中,我们必须将父类保存的数据保存在Parcelable对象中,否则会发生崩溃。

所以我这样来操作

bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());

父类保存数据和RectF自定义数据保存在里面,由于Bundle也是实现了 Parcelable接口和CREATE常量的,所以在View 中两个方法传递数据是OK的。

@Override
protected Parcelable onSaveInstanceState() {
final Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
bundle.putFloat(INSTANCE_TEXT_SIZE, getProgressTextSize());
bundle.putFloat(INSTANCE_REACHED_BAR_HEIGHT, getReachedBarHeight());
bundle.putFloat(INSTANCE_UNREACHED_BAR_HEIGHT, getUnreachedBarHeight());
bundle.putInt(INSTANCE_REACHED_BAR_COLOR, getReachedBarColor());
bundle.putInt(INSTANCE_UNREACHED_BAR_COLOR, getUnreachedBarColor());
bundle.putInt(INSTANCE_MAX, getMax());
bundle.putInt(INSTANCE_PROGRESS, getProgress());
bundle.putString(INSTANCE_SUFFIX, getSuffix());
bundle.putString(INSTANCE_PREFIX, getPrefix());
bundle.putBoolean(INSTANCE_TEXT_VISIBILITY, getProgressTextVisibility());
return bundle;
}
复制代码

在onRestoreInstanceState方法中,我们需要讲State强制转化成Bundle对象

@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
final Bundle bundle = (Bundle) state;
mTextColor = bundle.getInt(INSTANCE_TEXT_COLOR);
mTextSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
mReachedBarHeight = bundle.getFloat(INSTANCE_REACHED_BAR_HEIGHT);
mUnreachedBarHeight = bundle.getFloat(INSTANCE_UNREACHED_BAR_HEIGHT);
mReachedBarColor = bundle.getInt(INSTANCE_REACHED_BAR_COLOR);
mUnreachedBarColor = bundle.getInt(INSTANCE_UNREACHED_BAR_COLOR);
initializePainters();
setMax(bundle.getInt(INSTANCE_MAX));
setProgress(bundle.getInt(INSTANCE_PROGRESS));
setPrefix(bundle.getString(INSTANCE_PREFIX));
setSuffix(bundle.getString(INSTANCE_SUFFIX));
setProgressTextVisibility(bundle.getBoolean(INSTANCE_TEXT_VISIBILITY) ? ProgressTextVisibility.Visible : ProgressTextVisibility.Invisible);
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
return;
}
super.onRestoreInstanceState(state);
}
复制代码

具体的细节,大家可以在留言区一起讨论,交流学习。

另外我当时为了和普通的百分数进度条对比,也做了个普通的进度条,效果如下:

实现细节: 也就是我们用一个横向的ProgressBar,百分数是一个textView然后下一个定时器,不断的更新textView的数值。 只是重点为了给大家分享自定义的百分数进度条的效果,所以我注视了这部分代码。相应的调整下代码,运行程序就可以看到这个效果。

步骤一: 在布局中放开这段代码,注释掉相应的自定义的布局代码

<!--<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_marginTop="50dp"
android:orientation="vertical"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/pb_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" />
<TextView
android:id="@+id/tvpb"
android:text="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/pb_image"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>-->
复制代码

步骤二: 在MainActivity中放开这段代码,注释掉关于自定义的代码:

/*mPb_button = (ProgressBar) findViewById(R.id.pb_button);
mPb_textView = (TextView) findViewById(R.id.tvpb);
mPb_image = (ImageView) findViewById(R.id.pb_image);
new Thread(){
@Override
public void run() {
int i =0;
while (i<=100){
i++;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
final int j =i;
mPb_button.setProgress(i);
runOnUiThread(new Runnable() {
@Override
public void run() {
mPb_textView.setText(j+"%");
}
});
}
if (i>100) {
mHandler.sendEmptyMessage(0);
}
}
}.start();*/
复制代码
操作完前两步之后,运行程序即可看到上图效果。

项目源码:https://github.com/yangziling/NumberProgressBar.git

关注职场黑手杨,会持续有原创推送分享!

欢迎转发,分享!长按识别二维码关注