进度条类组件(进度条ProgressBar和拖动条SeekBar)
- 高级UI组件可分为四类:
(1).进度条类组件:包括进度条、拖动条和星级评分条。
(2).图像类组件:包括图像视图、图像切换器和网格视图。
(3).列表类组件:包括下拉列表框和列表视图。
(4).通用组件:包括滚动视图和选项卡。 - 进度条类组件(进度条ProgressBar)
- 进度条:当一个应用运行时,用户是无法通过显示界面看到后台效果的,根本不知道程序是否在执行以及程序执行的进度,可以使用进度条来显示程序执行的进度。Android中的进度条有两种显示形式,如果想显示实时进度就选用水平进度条;如果只想显示正在加载就选用圆形进度条。
在activity_main.xml文件中,用ProgressBar标签来定义进度条。
可以看到默认为圆形进度条。 - 属性:
-
android:layout_width :取值为match_content,即与父容器宽度相同。
-
android:layout_height :取值为wrap_content,即高度为包裹其自身内容。
-
style :设置进度条的显示形式。该属性的属性值可以通过两种方式来进行设置:
- 通过主题属性来进行设置:在Android SDK中提供了一些与主题相关的属性,通过引用这些属性可以改变进度条的样式。主题可能会随着Android版本的变化而变化,进度条的样式可能也会变化。如下为Android6.0的主题相关属性和对应的进度条样式:
- **通过Android定义好的样式资源来设置:**下面列举几个常用的样式资源:
示例:
- 通过主题属性来进行设置:在Android SDK中提供了一些与主题相关的属性,通过引用这些属性可以改变进度条的样式。主题可能会随着Android版本的变化而变化,进度条的样式可能也会变化。如下为Android6.0的主题相关属性和对应的进度条样式:
-
android:max :设置进度条的最大进度制。
-
android:progress :设置进度条的当前进度。
-
- 如何让进度条显示耗时程序运行的实时进度:
创建一个线程,在这个线程中来循环获取耗时操作完成的进度,并根据这个进度来更新进度条的进度。
示例:
先给进度条组件定义一个id:
然后在Java代码中进行如下操作:
package com.example.progressbardemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//第一步:
//定义一个进度条对象
private ProgressBar progressBar;
//定义一个整型变量来记录完成进度
private int progress=0;
//定义一个用于处理消息的handle对象(Android不支持在主线程中更新组件,就提供了一个消息处理对象android.os.Handle)
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第二步:获取进度条组件
progressBar=findViewById(R.id.progress);
//第三步:用一个匿名内部类实例化handle对象来与子线程传递消息,更新UI组件进度条的进度
handler=new Handler(){
//重写handleMessage()
@Override
public void handleMessage(@NonNull Message msg) {
//首先进行第四步:new一个线程来模拟耗时程序
//第八步:判断进度是否完成,并进行相应操作
if(msg.what==0x111){
//更新进度条的进度为当前已完成的进度
progressBar.setProgress(progress);
}else{
//弹出一个消息提示框来提醒用户耗时操作已完成
Toast.makeText(MainActivity.this,"耗时操作已完成",Toast.LENGTH_LONG).show();
//使用View类中的GONE常量来设置进度条组件不显示(进度已完成,不需要再显示进度条)
progressBar.setVisibility(View.GONE);
}
}
};
//第四步:new一个线程来模拟耗时程序(与Java创建线程方法基本一样)
new Thread(new Runnable() {
@Override
public void run() {
//使用一个死循环来不停的获取耗时操作的进度
while(true){
//用耗时操作doWork()的返回值来更新完成的进度,doWork()是第五步创建的
progress=doWork();
//第六步:创建并实例化一个消息对象用来与主线程传递消息
Message m=new Message();
//第七步:判断当前进度是否完成,并进行相应回应
if(progress<100){
//定义一个消息代码,代表进度未完成(类似于HTTP中的状态码)
m.what=0x111;
//将进度未完成发送给handle对象
handler.sendMessage(m);
}else{
//定义一个消息代码,代表进度已完成
m.what=0x110;
//将进度未完成发送给handle对象
handler.sendMessage(m);
//进度已完成就不需要再进行判断,需要退出死循环
break;
}
}
}
//第五步:创建一个doWork()来模拟耗时操作
private int doWork(){
//改变完成进度,这里模拟为经过200毫秒进度增加一个随机数
progress+=Math.random()*10;
//让线程睡眠200毫秒来模拟耗时操作进行了200毫秒
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//返回当前完成的进度
return progress;
}
}).start();//记得调用start()来开启线程
}
}
运行结果:
耗时操作未完成:
耗时操作已完成:
3. 进度条类组件(拖动条SeekBar)
- 拖动条:是进度条的一个子类,允许用户通过拖动的方式来调整某种数值。
在activity_main.xml文件中,用SeekBar标签来定义拖动条。
- 属性
- android:layout_width :取值match_parent,即与父容器相同。
- android:layout_height :取值wrap_content,即包裹其自身内容。
- android:max和android:progress :设置最大进度和当前进度。SeekBar是ProgressBar的子类,所以SeekBar标签中也可以使用ProgressBar标签中的属性。
- android:thumb :改变拖动条的图标。
示例:
提前准备一个企鹅图片并放在mipmap目录下:
添加android:thumb属性并赋值:
- 在用户拖动拖动条时获取改变后的值:
首先为拖动条定义一个id:
在Java文件中进行如下操作:
package com.example.seekbardemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取拖动条
SeekBar seekBar=findViewById(R.id.seekbar);
//为拖动条设置进度改变监听器
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
//以此匿名内部类作为参数,会自动重写以下三个方法
@Override//进度改变时执行的方法
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Toast.makeText(MainActivity.this,"进度改变:"+progress,Toast.LENGTH_SHORT).show();
}
@Override//开始触摸的时候执行的方法
public void onStartTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this,"开始触摸",Toast.LENGTH_SHORT).show();
}
@Override//停止触摸时执行的方法啊
public void onStopTrackingTouch(SeekBar seekBar) {
Toast.makeText(MainActivity.this,"停止触摸",Toast.LENGTH_SHORT).show();
}
});
}
}
运行结果:
刚开始运行,拖动条的按钮停留在当前进度值为5的地方:
触摸图标:
拖动图标:
停止触摸: