ProgressBar可以作為一些操作過(guò)程中的視覺(jué)指示器,可以將操作進(jìn)度實(shí)時(shí)的反饋給用戶(hù),有時(shí)也會(huì)使用第二進(jìn)度條用以輔助顯示,例如我們?cè)谟^看視頻時(shí),第一進(jìn)度條可以顯示當(dāng)前播放進(jìn)度,而第二進(jìn)度條則用以顯示緩沖進(jìn)度,更好地提高用戶(hù)體驗(yàn)。
同時(shí),對(duì)于某些不確定的情況下,比如網(wǎng)絡(luò)連接時(shí),可以使用轉(zhuǎn)圈的動(dòng)畫(huà)作為一個(gè)進(jìn)度指示器,提示用戶(hù)此時(shí)正在加載操作。
對(duì)于如何使用ProgressBar,API文檔也給了一個(gè)代碼樣例:
public class MyActivity extends Activity {
private static final int PROGRESS = 0x1;
private ProgressBar mProgress;
private int mProgressStatus = 0;
private Handler mHandler = new Handler();
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.progressbar_activity);
mProgress = (ProgressBar) findViewById(R.id.progress_bar);
// Start lengthy operation in a background thread
new Thread(new Runnable() {
public void run() {
while (mProgressStatus < 100) {
mProgressStatus = doWork();
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
}
}).start();
}
}
從示例代碼中可以看出,doWork方法屬于耗時(shí)操作,因此這里新開(kāi)了一個(gè)線(xiàn)程(PS:耗時(shí)操作不能在主線(xiàn)程UI中運(yùn)行,否則可能會(huì)造成ANR,即應(yīng)用程序無(wú)響應(yīng)的情況,這里應(yīng)該注意)。對(duì)于將耗時(shí)操作的進(jìn)度反饋到UI線(xiàn)程,也有較多方法(后面課程會(huì)詳細(xì)講解),這里采用了Handler的post方法,將實(shí)時(shí)操作進(jìn)度反饋到UI線(xiàn)程中的ProgressBar中。最后,新開(kāi)了一個(gè)線(xiàn)程,不要忘記調(diào)用它的start方法,啟動(dòng)線(xiàn)程。
在布局文件中引入一個(gè)ProgressBar可以使用一個(gè)ProgressBar標(biāo)簽,還需要一些屬性修飾,下面對(duì)常用屬性進(jìn)行一下介紹:
進(jìn)度條的樣式,Android提供了幾種原生的進(jìn)度條樣式,可以通過(guò)style屬性在布局文件中進(jìn)行設(shè)置。
這么解釋不夠直觀,下面通過(guò)一個(gè)小實(shí)例來(lái)對(duì)上面進(jìn)度條樣式和屬性進(jìn)行學(xué)習(xí)。
布局代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--水平進(jìn)度條-->
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="50"
android:secondaryProgress="60" />
<!-- 小進(jìn)度條-->
<ProgressBar
style="@android:style/Widget.ProgressBar.Small"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--大進(jìn)度條-->
<ProgressBar
style="@android:style/Widget.ProgressBar.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ProgressBar
style="@android:style/Widget.ProgressBar.Inverse"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ProgressBar
style="@android:style/Widget.ProgressBar.Large.Inverse"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ProgressBar
style="@android:style/Widget.ProgressBar.Small.Inverse"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
布局文件中定義了六種樣式的進(jìn)度條,并對(duì)第一個(gè)進(jìn)度條設(shè)置了max(最大值)、progress(當(dāng)前進(jìn)度)、secondaryProgress(第二進(jìn)度)等屬性,下面運(yùn)行實(shí)例觀察一下不同樣式進(jìn)度條的外觀差異:
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/9-1.png" alt="這里寫(xiě)圖片描述" />
除了上述樣式的進(jìn)度條之外,還有顯示在標(biāo)題欄上的進(jìn)度條, 布局代碼中添加了兩個(gè)按鈕:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_show"
android:text="顯示標(biāo)題欄進(jìn)度條"
android:onClick="show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_dismiss"
android:text="隱藏標(biāo)題欄進(jìn)度條"
android:onClick="dismiss"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Activity代碼如下:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//確定進(jìn)度的標(biāo)題欄進(jìn)度條
requestWindowFeature(Window.FEATURE_PROGRESS);
//不確定進(jìn)度的標(biāo)題欄進(jìn)度條
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main);
}
public void show(View view) {
setProgressBarVisibility(true);
setProgress(800);
setProgressBarIndeterminateVisibility(true);
}
public void dismiss(View view) {
setProgressBarVisibility(false);
setProgressBarIndeterminateVisibility(false);
}
}
這里調(diào)用了Activity類(lèi)的requestWindowFeature方法傳入Window.FEATURE_PROGRESS參數(shù)顯示有進(jìn)度的標(biāo)題欄進(jìn)度條,傳入Window.FEATURE_INDETERMINATE_PROGRESS參數(shù)則顯示不帶進(jìn)度的標(biāo)題欄進(jìn)度條。注意這個(gè)方法要在setContentView方法之前調(diào)用,這里涉及到View繪制過(guò)程的知識(shí),這里只需要記住這個(gè)順序即可,后面還會(huì)從原理上講解為什么要放在setContentView的前面。
調(diào)用setProgressBarVisibility方法傳入布爾變量即可決定標(biāo)題欄進(jìn)度條的顯示與否,同理setProgressBarIndeterminateVisibility用以決定標(biāo)題欄不確定進(jìn)度條的顯示與否。
運(yùn)行項(xiàng)目實(shí)例如下:
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/9-2.png" alt="這里寫(xiě)圖片描述" />
這里需要說(shuō)明,使用Android Studio作為開(kāi)發(fā)工具的同學(xué)要注意:項(xiàng)目默認(rèn)的MainActivity繼承自AppCompatActivity,需改成Activity,同時(shí),在AndroidManifest文件中設(shè)置對(duì)應(yīng)的Activity屬性android:theme="@style/Theme.AppCompat.CompactMenu" (有頂部的標(biāo)題欄的主題),就可以正常顯示了。
上面介紹了標(biāo)題欄進(jìn)度條的顯示和隱藏,下面通過(guò)一個(gè)小例子了解一下進(jìn)度條是如何更新進(jìn)度的,我們模擬了一個(gè)下載過(guò)程。布局代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="download"
android:text="下載模擬" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下載進(jìn)度如下:"/>
<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:id="@+id/probar_download"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Activity.java代碼如下:
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar)findViewById(R.id.probar_download);
progressBar.setMax(100);
progressBar.setProgress(20);
}
public void download(View view){
new Thread(){
@Override
public void run() {
for (int i=0;i<100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.incrementProgressBy(1);
}
}
}.start();
}
}
這里新開(kāi)了一個(gè)線(xiàn)程用于模擬下載過(guò)程,并調(diào)用ProgressBar的increaseProgressBy方法,在原來(lái)的基礎(chǔ)上每次增加1。除了increaseProgressBy方法,還有如下表所示的常用方法,讀者可以自行測(cè)試它們的用法。
http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/9-3.png" alt="這里寫(xiě)圖片描述" />
運(yùn)行實(shí)例如下: http://wiki.jikexueyuan.com/project/twenty-four-Scriptures/images/9-4.png" alt="這里寫(xiě)圖片描述" />