ProgressBar 用来把操作进度可视化,还可以带一条次要进度(例如流媒体缓冲)。它有确定模式和不确定模式:不确定时转圈循环动画,适合任务时长未知。SeekBar 继承自 ProgressBar,区别是用户可以拖动手动调进度。
一、ProgressBar 样式怎么写

样式有两套写法:直接点 Widget 主题,或用系统 attr。Widget 侧常见:
-
Widget.ProgressBar.Horizontal
-
Widget.ProgressBar.Small / Large
-
Widget.ProgressBar.Inverse 以及 Small / Large 的 Inverse
写法:style="@android:style/Widget.ProgressBar.Small"。对应系统 attr:
-
?android:attr/progressBarStyle
-
progressBarStyleHorizontal / Inverse / Large / LargeInverse / Small / SmallInverse / SmallTitle
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- 等价:style="@android:style/Widget.ProgressBar.Horizontal" -->
重要方法:setProgress() 设当前进度,incrementProgressBy() 按增量加。常用属性:progressDrawable 画确定进度轨道,indeterminateDrawable 画不确定转圈。
二、自定义不确定模式转圈

三种写法:系统 Large、style 换 indeterminateDrawable、shape 画圆环再 rotate。
<!--系统-->
<ProgressBar
android:id="@+id/progressBar3"
style="@android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<!--通过样式自定义-->
<ProgressBar
style="@style/mProgress_circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<!--通过shape自定义-->
<ProgressBar
style="@style/mProgress_circle_shape_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
mProgress_circle 样式:
<style name="mProgress_circle">
<item name="android:indeterminateDrawable">@drawable/progressbar_circle</item>
<item name="android:minWidth">25dp</item>
<item name="android:minHeight">25dp</item>
<item name="android:maxWidth">60dp</item>
<item name="android:maxHeight">60dp</item>
</style>
progressbar_circle.xml:android:drawable 指向自定义菊花图,再 rotate 0→360。
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/voice_loading"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
</rotate>
mProgress_circle_shape_loading 指向 ring + sweep 渐变:
<style name="mProgress_circle_shape_loading">
<item name="android:indeterminateDrawable">@drawable/progress_circle_shape</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="8"
android:useLevel="false" >
<gradient
android:centerColor="#FFFFFF"
android:centerY="0.50"
android:endColor="#1E90FF"
android:startColor="#000000"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
三、animation-list 帧动画 Loading

主布局把 indeterminateDrawable 指到 @anim/progress_circle_loading_anim:
<LinearLayout
android:id="@+id/progressbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/my_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:minWidth="250dp"
android:minHeight="250dp"
android:indeterminateDrawable="@anim/progress_circle_loading_anim" />
</LinearLayout>
两帧素材:progress_loading_image_01.png、progress_loading_image_02.png

progress_circle_loading_anim.xml:
<?xml version="1.0" encoding="utf-8"?>
<animation-list android:oneshot="false" xmlns:android="http://schemas.android.com/apk/res/android">
<item android:duration="100" android:drawable="@drawable/progress_loading_image_01" />
<item android:duration="100" android:drawable="@drawable/progress_loading_image_02" />
</animation-list>
四、SeekBar:可拖的 ProgressBar
继承链:Object → View → ProgressBar → AbsSeekBar → SeekBar。因此它拥有 ProgressBar 全部能力,多了拖动手势。
监听进度:
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// fromUser 标识变化是否来自用户
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 开始触摸手势
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 结束触摸手势
}
});
自定义:progressDrawable 画轨道,thumb 画滑块。
<SeekBar
android:id="@+id/seekBar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:progressDrawable="@drawable/seekbar_progress_drawable1"
android:thumb="@drawable/seekbar_progress_thum_selector" />

seekbar_progress_drawable1.xml:background + clip 出来的 progress 层。
<?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="@drawable/progress_bar_n">
</item>
<item android:id="@android:id/progress">
<clip>
<nine-patch android:src="@drawable/progress_bar_p" />
</clip>
</item>
</layer-list>
seekbar_progress_thum_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/eq_seekbar_thumb_press" android:state_pressed="true"></item>
<item android:drawable="@drawable/eq_seekbar_thumb_normal"></item>
</selector>
也可以不用点九图,用 shape + gradient 画轨道:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape>
<corners android:radius="10dip" />
<gradient
android:angle="270"
android:centerColor="#ff000000"
android:centerY="0.45"
android:endColor="#ffAABD00"
android:startColor="#ffffffff" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dip" />
<gradient
android:angle="270"
android:centerColor="#ffFFFF00"
android:centerY="0.45"
android:endColor="#ff808A87"
android:startColor="#ffffffff" />
</shape>
</clip>
</item>
</layer-list>
| 控件 |
模式 / 能力 |
自定义入口 |
| ProgressBar |
确定进度 / 不确定转圈 |
progressDrawable / indeterminateDrawable |
| SeekBar |
可拖动,OnSeekBarChangeListener |
再加 android:thumb |
参考: Android简单自定义圆形和水平ProgressBar
一句话总结:ProgressBar 管「显示进度或转圈」;SeekBar 在此基础上可拖。自定义轨道用 progressDrawable / layer-list,转圈用 rotate、shape 或 animation-list,滑块用 thumb selector。