Android 自学之进度条ProgressBar
进度条(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 }
上面主程序里面①和②处就是设置了进度条的显示形式,一种是带进度的,一种是不带进度的。下面我们看看他们的效果图:
上面这个是带进度的进度条,那根很细的蓝色细线。
上面这个是不带进度的进度条,右上角那个圆圈