ProgressDialog是AlertDialog的子類,我們用它來顯示有進度條的Dialog。這種帶有進度的UI控制項在好多UI框架中都可以看到,當用戶執行一個操作時間較長的操作時,在一個設計良好的系統中應該要顯示一個進度條提示使用者目前處理的進度到哪了。在安裝應用程式和網路交互應用中最常見到進度條,安裝應用程式由於耗時長,所以需要指示使用者進度,網路交互由於網路環境的不穩定也需要指示使用者交互的進度(尤其是當你在上傳或下載大檔時)。所以進度條是一個很常用到的控制項。
Android為我們提供了一個很好用的內置處理進度條的Dialog,它就是ProgressDialog。ProgressDialog裡的進度條分為兩種:可確定值進度條和不可確定值進度條。可確定值進度條是指:系統能指示目前進度值,需要更新目前進度條的值,如果進度條到達一定值就表示完成進度。不可確定值進度條是指:系統指示需要等待,但是沒有給出目前進度,所以你無法得知目前進度到哪裡,只是能看到系統在處理,還需要等待的介面,所以說它沒有一個確定值。
我們來看一個最簡單的顯示ProgressDialog的代碼:
- ProgressDialog.show(this, "正在加载...", "系统正在处理您的请求");
上面代碼直接顯示了一個ProgressDialog,它是屬於不可確定值進度條的ProgressDialog,它的參數很簡單第一個參數是Context上下文資訊,第二個參數是Dialog的title標題,第三個參數則是Dialog的body要顯示的資訊,代碼的效果如下:
可以看到ProgressDialog顯示了一個在轉動的小圓圈,這個小圓圈將會永久轉動直到Dialog消失掉,所以這是一個不可確定值的進度條。運行代碼我們發現這個Dialog不可取消掉,它會一直存在直到你用代碼控制讓dialog消失,所以它是不可取消的,如果要讓用戶可以取消,要再後面添加兩個參數,分別是:
- ProgressDialog.show(this,
- "正在加载...", //標題
- "系统正在处理您的请求", //内容
- true, //是否不可確定值
- true);
上面使用show方法創建的不可確定值的ProgressDialog比較簡單,如果要創建一個可確定值的進度條dialog就會比較麻煩,因為你需要編寫一些額外的代碼來控制進度條。這邊創建ProgressDialog就需要通過new 創建一個新物件,它沒有Builder可以通過配置來生成。所以我們要做的就是:
- 創建ProgressDialog對象
- 設置它內部的進度條是可確定值的
- 將它顯示出來
- 更新進度條值,當進度完成後隱藏對話方塊
我們根據上面這幾步,創建一個可複用的可確定值的ProgressDialog。首先我們要給需要managed的Dialog分配一個id值,然後重寫onCreateDialog方法創建ProgressDialog。
- @Override
- protected Dialog onCreateDialog(int id) {
- switch(id){
- case PROGRESS_DIALOG :
- ProgressDialog pd = new ProgressDialog(this);
- pd.setTitle("进度条"); //設置標題
- pd.setMessage("正在处理请稍后..."); //設置body訊息
- pd.setMax(100); //進度條最大值是100
- pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //設置進度條樣式是 横向的
- return pd;
- }
- return super.onCreateDialog(id);
- }
在這裡我們重寫Activity的onCreateDialog方法,讓ProgressDialog變成是可複用的managed dialog。當點擊按鈕時我們調用:
- showDialog(PROGRESS_DIALOG);
將onCreateDialog方法裡創建的ProgressDialog物件顯示出來:
上面就是可確定值進度條ProgressDialog的效果,可是它的進度條不會動,這是因為你還沒用代碼去控制進度條的進度,所以這邊我們需要編寫一些額外代碼,當表單顯示時首先讓進度條歸零,然後用一個執行緒讓進度條每100ms增加1,所以總共要10秒才能讀完整個進度條。我們用Handler物件來處理,因為android中使用的是UI單執行緒模式,你自己創建執行緒不能訪問UI控制項,否則會拋出異常。而Handler會將需要執行的代碼放到UI執行緒去執行。所以我們先定義一個Handler內部類來改變進度條的值。
- private static final int PROGRESS_DIALOG = 1;
- int progressValue = 0; //保存进度条目前的进度值,当达到最大值时隐藏ProgressDialog
- ProgressDialog mProgressDialog ; //引用的ProgressDialog对象
- Handler progressHandler;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.dialog3);
- progressHandler = new Handler(){
- public void handleMessage(android.os.Message msg) {
- if(progressValue == 100){
- mProgressDialog.dismiss();
- }else{
- //设置进度条的值加1
- progressValue ++;
- mProgressDialog.incrementProgressBy(1);
- //如果进度条还没结束则100ms后进度条加1,循环调用每100ms就将进度条加1
- progressHandler.sendEmptyMessageDelayed(0, 100);
- }
- };
- };
- }
然後添加按鈕事件,當使用者點擊顯示可確定值ProgressDialog時,首先將進度條清0,然後發送第一條開始更新進度條的handler消息,因為handler消息處理方法內部有迴圈調用發送消息,所以只要第一次觸發程式就會每100ms發送一個更新消息,直到進度條值到達100,隱藏掉對話方塊。所有代碼如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="显示最简单的ProgressDialog"
- android:onClick="onClick1"
- />
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="显示可确定值的ProgressDialog"
- android:onClick="onClick2"
- />
- </LinearLayout>
- package com.king.dialog.uicontroller.dialog;
- import com.king.dialog.uicontroller.R;
- import android.app.Activity;
- import android.app.Dialog;
- import android.app.ProgressDialog;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.View;
- public class ProgressDialogActivity extends Activity {
- private static final int PROGRESS_DIALOG = 1;
- int progressValue = 0; //保存进度条目前的进度值,当达到最大值时隐藏ProgressDialog
- ProgressDialog mProgressDialog ; //引用的ProgressDialog对象
- Handler progressHandler;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.dialog3);
- progressHandler = new Handler(){
- public void handleMessage(android.os.Message msg) {
- if(progressValue == 100){
- mProgressDialog.dismiss();
- }else{
- //设置进度条的值加1
- progressValue ++;
- mProgressDialog.incrementProgressBy(1);
- //如果进度条还没结束则100ms后进度条加1,循环调用每100ms就将进度条加1
- progressHandler.sendEmptyMessageDelayed(0, 100);
- }
- };
- };
- }
- public void onClick1(View view){
- ProgressDialog.show(this,
- "正在加载...", //标题
- "系统正在处理您的请求", //内容
- true, //是否不可确定值
- true); // 是否可取消
- }
- @Override
- protected Dialog onCreateDialog(int id) {
- switch(id){
- case PROGRESS_DIALOG :
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setTitle("进度条"); //设置标题
- mProgressDialog.setMessage("正在处理请稍后..."); //设置body信息
- mProgressDialog.setMax(100); //进度条最大值是100
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //设置进度条样式是 横向的
- return mProgressDialog;
- }
- return super.onCreateDialog(id);
- }
- public void onClick2(View view){
- showDialog(PROGRESS_DIALOG);
- progressValue = 0;
- mProgressDialog.setProgress(0);
- progressHandler.sendEmptyMessage(0);
- }
- }
代碼運行效果如下:
使用者可以看到在走動的進度條,當進度條達到100時ProgressDialog就自動消失。這邊一個難點就是Handler的用法,這個以後會再仔細介紹,現在先瞭解Handler就是可以將代碼放到UI執行緒去執行即可。
參考來源: http://blog.csdn.net/comkingfly/article/details/6578722
