ProgressBar组件也是一组重要的组件,progressBar本身代表了进度条组件,它还派生了两个常用的组件,SeekBar和RatingBar。progress及其子类在用法上十分相似,只是显示界面有一定的区别,因此本节归为一类,针对共性讲解,并突出介绍它们的区别。
ProgressBar进度条
进度条也是UI界面中非常实用的组件,通常用于向用户显示某个耗时操作完成的百分比,进度条可以动态地显示进度,因此避免长时间地执行某个耗时操作,让用户感觉程序失去了响应,从而更好地提高用户界面的友好性。
Android支持几种风格的进度条,通过style属性可以为Progress指定风格,该属性支持:
@android:style/Widget.ProgressBar.Horizontal:水平进度条
@android:style/Widget.ProgressBar.普通大小的圆形进度条
@android:style/Widget.ProgressBar.Large :大圆形进度条
@android:style/Widget.ProgressBar.Large.Inverse:大圆形进度条
@android:style/Widget.ProgressBar.Small:小圆形进度条
@android:style/Widget.ProgressBar.Small.Inverse:小圆形进度条
常用属性
android:max 设置该进度条最大值
android:progress 设置进度条的已经完成的进度值
android:progressDrawable 设置该进度条的轨道对应的Drawable对象
android:indeterminate 该属性若为true,则进度条不精确显示进度
android:indeterminateDuration 设置不精确显示进度的持续时间
模拟耗时操作进度条:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progress"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progressDrawable="@drawable/my_bar"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 定义轨道的背景 -->
<item android:id="@android:id/background"
android:drawable="@android:drawable/progress_horizontal"/>
<!-- 定义完成轨道的样式 -->
<item android:id="@android:id/progress"
android:drawable="@drawable/ic_launcher"/>
</layer-list>
MainActivity.java
public class MainActivity extends Activity {
ProgressBar pb;
// 记录进度条位置
int position = 0;
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == 1) {
position += 1;
pb.setProgress(position);
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb=(ProgressBar) findViewById(R.id.progress);
new Thread(new Runnable() {
@Override
public void run() {
while(position<100){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}}
}).start();
}
}
效果图:
通过效果图可以看出:
当进度条走动时加载图片是一点一点加载的,直到图片完全展示出来。并且图片之间都会有一定的间隔。
Activity内置的进度条
系统内置进度条不需要使用Progress控件,它是直接由Activity的方法调用的。
public class MainActivity extends Activity {
Button b1,b2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置窗口特征:启用显示进度的进度条
requestWindowFeature(Window.FEATURE_PROGRESS);
//设置窗口特征:启动不显示进度的进度条
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
//如果事先调用该布局后设置进度条将抛出
// android.util.AndroidRuntimeException: requestFeature() must be called before adding content
setContentView(R.layout.activity_main);
b1=(Button) findViewById(R.id.btn1);
b2=(Button) findViewById(R.id.btn2);
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//显示不带进度的进度条
setProgressBarIndeterminateVisibility(true);
//显示带进度的进度条
setProgressBarVisibility(true);
//设置进度条的进度
setProgress(4500);
}
});
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//隐藏不带进度的进度条
setProgressBarIndeterminateVisibility(false);
setProgressBarVisibility(false);
}
});
}
}
效果图:
SeekBar拖动条
拖动条和进度条非常相似,只是进度条采用颜色填充来表明进度完成的程度,而拖动条则通过滑块的位置来标识数值因此拖动条通常用于对系统的某种数值进行调节,比如音量,播放MP3进度等。由于SeekBar继承Progress,因此Progress所支持的属性完全适用于SeekBar。SeekBar允许用户改变拖动条的滑块外观,改变方式android:thumb:指定一个Drawable对象,该对象将作为自定义滑块
MainActivity.java
public class MainActivity extends Activity {
ImageView img;
SeekBar bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img=(ImageView) findViewById(R.id.img);
bar=(SeekBar) findViewById(R.id.seekbar);
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
System.out.println("滑块停止触发该事件");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
System.out.println("点击滑块触发该事件");
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
//setAlpha在API 16 过时
img.setImageAlpha(progress);
}
});
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/b"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"
android:thumb="@drawable/ic_launcher"
/>
</LinearLayout>
效果图:
RatingBar星级评分
星级评分条与拖动条有相同的父类,AbsSeekBar,因此它们十分相似,实际上星级评分条与拖动条的用法,功能都十分接近:它们都允许用户通过拖动条来改变进度。RatingBar与SeekBar最大区别在于:RatingBar通过星星来表示进度。
常用XML属性
android:isIndicator 设置该星级评分是否允许用户改变(true为不允许修改)
android:numStars 设置星星总数量
android:rating 设置评分默认的星级
android:stepSize 设置每次最少需要改变多少个星级
MainActivity.java
public class MainActivity extends Activity {
ImageView img;
RatingBar rating;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView) findViewById(R.id.img);
rating=(RatingBar) findViewById(R.id.rating);
rating.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
//把255全部的alpha值平均分配给每个星星
@Override
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
img.setAlpha(rating/5);
}
});
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/b"/>
<!-- RatingBar的宽度不能为math_parent,这会导致显示不正常 -->
<RatingBar
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:max="255"
android:progress="255"
android:stepSize="0.5"/>
</LinearLayout>
效果图: