進度條(ProgressBar)也是UI界面中的一種非常使用的組件,通常用於向用戶顯示某個耗時完成的百分比。因此進度條可以動態的顯示進度,因此避免長時間地執行某個耗時操作時,讓用戶感覺程序失去了響應,從而更好的提高用戶界面的有好性。
Android支持幾種風格的進度條,通過Style屬性可以為進度條ProgressBar指定風格,該屬性支持一下幾個屬性值。
- @android:style/widget.ProgressBar.Horizontal————水平進度條
- @android:style/widget.ProgressBar.Inverse————不斷跳躍、旋轉畫面進度條
- @android:style/widget.ProgressBar.Large————大進度條
- @android:style/widget.ProgressBar.Large.Inverse————不斷跳躍、旋轉畫面的大進度條
- @android:style/widget.ProgressBar.Small————小進度條
- @android:style/widget.ProgressBar.Smal.Inversel————不斷跳躍、旋轉畫面的小進度條
除此之外,ProgressBar還支持下表的常用XML屬性
XML屬性 | 說明 |
android:max | 設置該進度條的最大值 |
android:progress | 設置該進度條的已完成進度值 |
android:progressDrawable | 設置該進度條的軌道的繪制形式 |
android:progressBarStyle | 默認進度條樣式 |
android:progressBarStyleHorizontal | 水平進度條樣式 |
android:progressBarStyleLarge | 大進度條樣式 |
android:progressBarStyleSmall | 小進度條樣式 |
上表中的android:progressDrawable用於指定進度條的軌道的繪制形式,該屬性可以指定一個LayerDrawable對象(該對象可以通過在xml文件中用<layer-list>元素進行配置)的引用。
ProgressBar提供了如下方法來操作完成百分比:
- setProgress(int):設置進度完成百分比。
- incrementProgressBy(int):設置進度條的進度增加或減少。當參數為正數時增加,反之則減少。
下面的程序簡單的示范了進度條的用法,改程序的界面布局文件只是定義了一個簡單的進度條,並指定了style屬性@android:style/widget.ProgressBar.Horizontal;即水平進度條,界面布局文件如下:
Layout/main.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent"> 6 7 <TextView 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="任務完成的進度" /> 11 12 <!-- 定義一個水平的進度條 --> 13 <ProgressBar android:id="@+id/bar" 14 android:layout_width="fill_parent" 15 android:layout_height="wrap_content" 16 android:max="100" 17 style="@android:style/Widget.ProgressBar.Horizontal"/> 18 19 20 <!-- 定義一個水平的進度條,並改變軌道外觀 --> 21 <ProgressBar android:id="@+id/bar2" 22 android:layout_width="fill_parent" 23 android:layout_height="wrap_content" 24 android:max="100" 25 style="@android:style/Widget.ProgressBar.Horizontal" 26 android:progressDrawable="@drawable/my_bar"/> 27 </LinearLayout>
上面的代碼layout/main.xml里面有兩個水平的進度條,但是第二個我們改變的軌道外觀,外觀被定義為@drawable/my_bar,因此我們還需要看看
drawable-mdpi/my_bar.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 3 <!-- 定義軌道的背景 --> 4 <item android:id="@android:id/background" 5 android:drawable="@drawable/no" /> 6 <!-- 定義軌道上已完成部分的樣式 --> 7 <item android:id="@android:id/progress" 8 android:drawable="@drawable/ok" /> 9 </layer-list>
drawable-mdpi/my_bar.xml 這個文件定義了軌道的背景為no這張圖片,已完成的部分為ok這張圖片。
主程序用了一個數組填充的任務模擬了耗時操作,並以進度條來標識任務的完成百分比。
com.example.progressbar.ProgressBarTest.java
1 package com.example.progressbar; 2 3 import android.support.v7.app.ActionBarActivity; 4 import android.support.v7.app.ActionBar; 5 import android.support.v4.app.Fragment; 6 import android.os.Bundle; 7 import android.os.Handler; 8 import android.os.Message; 9 import android.view.LayoutInflater; 10 import android.view.Menu; 11 import android.view.MenuItem; 12 import android.view.View; 13 import android.view.ViewGroup; 14 import android.widget.ProgressBar; 15 import android.os.Build; 16 17 public class ProgressBarTest extends ActionBarActivity { 18 19 //該程序模擬填充長度為100的數組 20 private int[] data = new int[100]; 21 int hasData = 0; 22 //記錄ProgressBar的完成進度 23 int status = 0; 24 25 @Override 26 protected void onCreate(Bundle savedInstanceState) { 27 super.onCreate(savedInstanceState); 28 setContentView(R.layout.main); 29 //獲得界面布局里面的進度條組件 30 final ProgressBar bar = (ProgressBar) findViewById(R.id.bar); 31 final ProgressBar bar2 = (ProgressBar) findViewById(R.id.bar2); 32 //創建一個負責更新進度條的Handler 33 final Handler mHandler = new Handler(){ 34 @Override 35 public void handleMessage(Message msg) { 36 37 if (msg.what == 0x111) { 38 bar.setProgress(status); 39 bar2.setProgress(status); 40 } 41 } 42 }; 43 44 //啟動線程來執行任務 45 new Thread(){ 46 public void run() { 47 while (status < 100) { 48 // 獲取耗時操作的完成百分比 49 status = doWork(); 50 // 發送消息到Handler 51 Message m = new Message(); 52 m.what = 0x111; 53 // 發送消息 54 mHandler.sendMessage(m); 55 } 56 57 }; 58 }.start(); 59 60 } 61 62 //模擬一個耗時的操作 63 private int doWork() { 64 data[hasData++] = (int) (Math.random() * 100); 65 66 try { 67 Thread.sleep(100); 68 } catch (InterruptedException e) { 69 e.printStackTrace(); 70 } 71 72 return hasData; 73 } 74 }
運行后的效果圖:
顯示在標題上的進度條:
還有一種進度條,他可以直接顯示在窗口的標題上,這種進度條甚至不需要使用ProgressBar組件,他直接由activity的方法啟用。為了在窗口上顯示進度條我們需要經過一下兩步:
- 調用Activity的requestWindowFeatures()方法,該方法根據傳入的參數可啟用特定的窗口特征,比如:傳入Window.FEATURE_INDETERMINATE_PROGRESS在窗口標題上顯示不帶進度的進度條;傳入Window.FEATURE_PROGRESS則是顯示進度的進度條。
- 調用Activity的setProgressBarVisibility(boolean)或setProgressBarIndeterminateVisibility(boolean)方法即可控制進度條的顯示或隱藏。
界面布局main.xml的代碼很簡單,就是添加兩個按鈕
Layout/main.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:orientation="horizontal" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent"> 6 7 <Button android:id="@+id/bn01" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:layout_gravity="center_horizontal" 11 android:text="顯示"/> 12 13 <Button android:id="@+id/bn02" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:layout_gravity="center_horizontal" 17 android:text="隱藏"/> 18 19 </LinearLayout>
下面我們來看看主程序是如何設置的
com.example.titleprogressbar.TitleProgressBar.java
1 package com.example.titleprogressbar; 2 3 import android.support.v7.app.ActionBarActivity; 4 import android.support.v7.app.ActionBar; 5 import android.support.v4.app.Fragment; 6 import android.os.Bundle; 7 import android.view.LayoutInflater; 8 import android.view.Menu; 9 import android.view.MenuItem; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.view.ViewGroup; 13 import android.view.Window; 14 import android.widget.Button; 15 import android.os.Build; 16 17 public class TitleProgressBar extends ActionBarActivity { 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 //設置窗口特征:啟用顯示進度的進度條 ① 23 requestWindowFeature(Window.FEATURE_PROGRESS); 24 //設置窗口特征:啟用不顯示進度的進度條 ② 25 // requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 26 setContentView(R.layout.main); 27 28 Button bn1 = (Button) findViewById(R.id.bn01); 29 Button bn2 = (Button) findViewById(R.id.bn02); 30 bn1.setOnClickListener(new OnClickListener() { 31 32 @Override 33 public void onClick(View v) { 34 //顯示不帶進度的進度條 35 setProgressBarIndeterminateVisibility(true); 36 //顯示帶進度的進度條 37 setProgressBarVisibility(true); 38 //設置進度條的進度 39 setProgress(4500); 40 } 41 }); 42 bn2.setOnClickListener(new OnClickListener() { 43 44 @Override 45 public void onClick(View v) { 46 //隱藏不帶進度的進度條 47 setProgressBarIndeterminateVisibility(false); 48 //隱藏帶進度的進度條 49 setProgressBarVisibility(false); 50 } 51 }); 52 53 } 54 }
上面主程序里面①和②處就是設置了進度條的顯示形式,一種是帶進度的,一種是不帶進度的。下面我們看看他們的效果圖:
上面這個是帶進度的進度條,那根很細的藍色細線。
上面這個是不帶進度的進度條,右上角那個圓圈