今天要学的是一个特定场合要用到的控件——进度条控件。进度条的作用不言而喻,而在实际使用中,通常会有两种类型的进度条:横向进度条和圆形进度条。当然,ProgressBar 也是支持这两种类型的,可以应对大多数的开发场景。
ProgressBar 是一个图形类型的控件,用来展示当前进度,可以是下载、跳转、切换、保存等等任何可能比较耗时的任务,它在很多场景下对用户体验是有很大帮助的,所以我们千万不能忽略它,要学会灵活的使用,否则用户可能会以为发送了卡顿或者 ANR 从而关闭应用,大大减低用户体验。
我们先来看看 ProgressBar 的常用属性:
style
为android:attr/progressBarStyleHorizontal
可以设置成横向进度条的样式。基本上常用的属性就这么多,都还比较好理解,这只是添加了一个进度条,如果我们是android:indeterminate
模式,那只需要展示进度条和隐藏即可;但是如果android:indeterminate
为 false,在实际使用中我们还需要在代码的逻辑里去实时更新进度条,这就需要配合 Java 的 api 来完成了。
android:max
属性相通。android:progress
属性相通。android:secondaryProgress
属性相通。android:indeterminate
属性相通。Ok,我们有了布局设置以及 API 控制,就可以开始完成一个进度条的开发了,本节将在 Activity 中启动一个子线程,在子线程中通过 sleep 300 毫秒来模拟一个耗时任务,并在执行任务的过程中不断更新进度条。
首先编写布局,我们添加一个横向非不确定进度条展示精确精度和一个圆形不确定进度条不展示确定进度,然后添加一个 TextView 用于展示具体的进度情况,代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar android:id="@+id/progressBar_horizontal" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="30dp" android:indeterminate="false" android:max="100" android:minWidth="200dp" android:minHeight="50dp" android:progress="1" />
<ProgressBar android:id="@+id/progressBar_circle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:minWidth="50dp" android:minHeight="50dp" />
<TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/progressBar_horizontal" android:layout_alignLeft="@+id/progressBar_horizontal" />
</RelativeLayout>
布局完成效果如下,上方有一个进度为 1 的横向进度条,中间有一个循环转圈的圆形进度条。目前任务还没开启,所以还没有进度展示,TextView 内容为空。
下面通过 Java 编写后台耗时任务,并同步更新进度条:
package com.emercy.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
private ProgressBar progressBar;
private int progressStatus = 0;
private TextView textView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progressBar_horizontal);
textView = findViewById(R.id.textView);
new Thread(new Runnable() {
public void run() {
while (progressStatus < 100) {
progressStatus += 1;
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressStatus);
textView.setText(progressStatus + "/" + progressBar.getMax());
}
});
try {
// sleep 300毫秒模拟耗时任务
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
}
在上面的代码中,横向 ProgressBar 会在每 300 毫秒更新一次进度(进度增加多少可以根据具体场景,比如下载量、保存量、解析量等等),更新进度通过setProgress()
接口完成。另外本节运用了 Handler 去完成更新,因为耗时操作我们通常会放在子线程,但是 Android 系统要求不能在子线程中进行 UI 操作,所以我们通过 Handler 完成子线程到主线程的切换(具体的使用方法会在后面 Handler 章节详细讲解,这里重点关注 ProgressBar 的使用),直到进度条增加为 100,表示任务完成;而另一个进度条会循环 loading,此时会一直循环播放进度动画,直到主动关闭,下面是一张代码的效果图:
本节学习了进度条控件,介绍 PregressBar 的主要属性及常用 API,完成了一个耗时任务的进度实时更新程序。ProgressBar 主要针对需要执行耗时任务并且阻塞UI的场景,目的是给用户一个比较好的等待体验。
当然如果对 UI 要求很高,或者需要很复杂的 loading 动画的时候,ProgressBar 也许就不尽如人意了。这时候需要通过自定义 View 完全实现一个自己的进度条控件,这个大家在学习了自定义控件之后就可以轻松完成,关于自定义控件我们也会在后面的章节陆续学习到,敬请期待!
0/1000