SeekBar
(拖动进度条,也简称:拖动条)是 ProgressBar 进度条的一个扩展。它增加了一个可拖动的拇指,用户可以触摸并向左或向右拖动来设置当前的进度级别。
拖动进度条最常用的地方就是音乐播放器或者视频播放器场景,通过滑动拖动进度条来进行音量控制或者播放进度的控制。一些应用的相关设置项如亮度,音量等等场景也是使用非常多的。
SeekBar 是 ProgressBar
的子类,所以 ProgressBar 的属性和特性都是可以使用的,增加了一个滑块的属性和可以实时监听滑动的进度值的特性。
# 基本属性
自己的属性:
android:thumb
:指定滑块drawable资源
继承自 ProgressBar 的属性:
android:max
:进度条的进度最大值,默认值100android:min
:进度条的进度最小值,默认值0android:progress
:进度条当前进度值android:progressDrawable
:设置进度轨道对应的Drawable对象android:secondaryProgress
:二级进度值,默认值0,多数用于标记参考进度
注意:继承属性中的不确定进度属性,在拖动进度条中没有任何意义,使用后将无法拖动进度。
# 获取和监听进度
获取进度可以通过 getProgress()
方法获取一级进度,getSecondaryProgress()
方法获取二级进度,拖动进度条中,二级进度一般用于标记一些重要的节点进度参考使用。
可以通过设置 SeekBar.OnSeekBarChangeListener
来监听进度(一级进度)变化,有三个对应通知的方法:
onProgressChanged
:进度发生改变时通知onStartTrackingTouch
:开始按住SeekBar时通知onStopTrackingTouch
:释放SeekBar时通知
注意:拖动进度条滑块操作的进度是一级进度,二级进度是继承自 ProgressBar 的,需要主动设置进度和获取,且进度条进度监听通知的也是一级进度变化。
# 基本用法示例
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<!-- 拖动进度条,当前进度50,二级进度60,最大进度100,最小进度0 -->
<SeekBar
android:id="@+id/seekbar_demo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:min="0"
android:progress="50"
android:secondaryProgress="60" />
</LinearLayout>
代码:
SeekBar seekBar = findViewById(R.id.seekbar_demo);
// 监听进度变化
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// 进度发生变化通知,progress:当前一级进度,fromUser:是否是用户滑动触发的
Log.d(TAG, "onProgressChanged: progress = " + progress
+ ", secondaryProgress = " + seekBar.getSecondaryProgress()
+ ", fromUser = " + fromUser);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 当开始按住seekBar时通知
Log.d(TAG, "onStartTrackingTouch: ");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 当释放seekBar时通知
Log.d(TAG, "onStopTrackingTouch: ");
}
});
// 获取当前的一级进度
int progress = seekBar.getProgress();
Log.d(TAG, "getProgress: progress = " + progress);
// 获取二级进度, 拖动条中使用场景较少,一般用于标记重要进度节点参考使用
int secondaryProgress = seekBar.getSecondaryProgress();
Log.d(TAG, "getSecondaryProgress: secondaryProgress = " + secondaryProgress);
// 设置一级进度为60,会有进度回调
seekBar.setProgress(60);
// 设置二级进度为80,没有进度回调
seekBar.setSecondaryProgress(80);
运行日志输出:
getProgress: progress = 50
getSecondaryProgress: secondaryProgress = 60
onProgressChanged: progress = 60, secondaryProgress = 60, fromUser = false
onStartTrackingTouch:
onProgressChanged: progress = 59, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 58, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 57, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 56, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 55, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 54, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 53, secondaryProgress = 80, fromUser = true
onProgressChanged: progress = 54, secondaryProgress = 80, fromUser = true
onStopTrackingTouch:
效果图:
# 自定义进度样式
系统默认的拖动进度条的样式是满足不了各种产品的 UI 设计的,所以就需要自定义样式的进度条,自定义样式进度条方式有很多,一般主要有两种,一种是自定义进度条的相关 drawable
资源来实现,还有一种是自定义 View
绘制的方式实现。
在这里我们主要进行前者自定义指定 drawable 资源方式实现,自定义 View 实现方式在后续会有相关详细的介绍。
可以自定义拖动进度条的背景、二级进度、一级进度和thumb滑块的资源来实现个性化样式,在这里就简单实现下,了解自定义的原理和方式,想要好看的效果还是需要专业的 UI 人员来设计配色方案的。
- 创建
thumb
滑块的相关 drawable 资源文件,可以使用 drawable shape 或者图片资源实现,这里使用前者来实现:
shape_seekbar_normal.xml:正常滑块样式
<?xml version="1.0" encoding="utf-8"?>
<!-- 滑块:正常状态形状样式 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> <!-- 矩形 -->
<!-- 大小 -->
<size
android:width="20dp"
android:height="20dp" />
<!-- 渐变色背景 -->
<gradient
android:angle="0"
android:endColor="#2196F3"
android:startColor="#FF5722" />
<!-- 描边 -->
<stroke
android:width="4dp"
android:color="#4CAF50" />
</shape>
shape_seekbar_press.xml:按压状态滑块样式
<?xml version="1.0" encoding="utf-8"?>
<!-- 滑块:按压状态形状样式 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> <!-- 矩形 -->
<!-- 大小 -->
<size
android:width="20dp"
android:height="20dp" />
<!-- 背景 -->
<solid android:color="#FFFFFF" />
<!-- 描边 -->
<stroke
android:width="4dp"
android:color="#4CAF50" />
</shape>
selector_seekbar_thumb.xml:滑块状态选择器
<?xml version="1.0" encoding="utf-8"?>
<!-- thumb 滑块状态选择器 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@drawable/shape_seekbar_normal" />
<item android:state_pressed="true" android:drawable="@drawable/shape_seekbar_press" />
</selector>
- 创建拖动进度条的样式 drawable 文件,自定义一个层级的 drawable 资源文件,并指定其对应资源的特定 id:
progress_seekbar_bg.xml:定义拖动进度条的三层显示的样式
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 3层的顺序即为显示时的叠加层级 -->
<!-- 第一层:背景资源,必须指定此id来区分:@android:id/background -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<solid android:color="#CCCCCC" />
</shape>
</item>
<!--
第二层:二级进度条的资源, 必须指定此id来区分:@android:id/secondaryProgress
一般用于标记特殊进度位置
-->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<solid android:color="#99FF9800" />
</shape>
</clip>
</item>
<!-- 第三层:一级进度条的颜色,也可以直接替换成图片,必须指定此id来区分:@android:id/progress -->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<!-- 单色填充 -->
<!--<solid android:color="#8BC34A" />-->
<!-- 渐变色填充 -->
<gradient
android:angle="0"
android:startColor="#A0D9F3"
android:endColor="#2196F3" />
</shape>
</clip>
</item>
</layer-list>
- 使用创建的自定义样式资源
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<!-- 拖动进度条,当前进度50,二级进度60,最大进度100,最小进度0 -->
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:min="0"
android:progress="50"
android:progressDrawable="@drawable/progress_seekbar_bg"
android:secondaryProgress="60"
android:thumb="@drawable/selector_seekbar_thumb" />
<!-- 拖动进度条: 背景条填满控件大小,设置左右padding为0dp即可 -->
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:max="100"
android:min="0"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:paddingEnd="0dp"
android:paddingRight="0dp"
android:progress="50"
android:progressDrawable="@drawable/progress_seekbar_bg"
android:secondaryProgress="60"
android:thumb="@drawable/selector_seekbar_thumb" />
</LinearLayout>
效果图:
注意:SeekBar 默认背景条不会充满其控件显示,会预留滑块大小左右的内边距离,如需背景填满控件的大小,可以设置相应左右方向的
paddingXXX
大小为0dp
即可,同时需要做好相应进度和显示的适配。
# 结束
本节介绍了拖动进度条控件的常用属性和相关使用方法,并实现了自定义进度条样式。更多进度条的属性和用法请参考:SeekBar (opens new window)。