Android开发之进度条ProgressBar
<h1 class="_1RuRku"> </h1><h1>说明</h1>
<p>ProgressBar一般用于显示一个过程,例如数据加载过程,文件下载进度,音乐播放进度等。</p>
<h3>默认形式ProgressBar</h3>
<p>默认方式下,ProgressBar显示为圆形进度,循环转圈,不显示具体的进度值,控制其显隐藏即可,如下</p>
<p> </p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="400" data-height="82"><img src="https://upload-images.jianshu.io/upload_images/3030704-a330aa60e50e037c.png?imageMogr2/auto-orient/strip|imageView2/2/w/400/format/webp"></div>
</div>
<div class="image-caption">默认</div>
</div>
<p> </p>
<p>适用于界面加载</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"> <span class="token comment">//xml中
<span class="token operator"><ProgressBar
android<span class="token operator">:layout_width<span class="token operator">=<span class="token string">"wrap_content"
android<span class="token operator">:layout_height<span class="token operator">=<span class="token string">"wrap_content" <span class="token operator">/<span class="token operator">>
<span class="token comment">//代码中控制显隐藏
mProgressBar <span class="token operator">= <span class="token punctuation">(ProgressBar<span class="token punctuation">) <span class="token function">findViewById<span class="token punctuation">(R<span class="token punctuation">.id<span class="token punctuation">.progress_bar_main<span class="token punctuation">)<span class="token punctuation">;
mProgressBar<span class="token punctuation">.<span class="token function">setVisibility<span class="token punctuation">(View<span class="token punctuation">.VISIBLE<span class="token punctuation">)<span class="token punctuation">;
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<h3>横向ProgressBar</h3>
<p>横向带进度的进度条,通过设置ProgressBar的Style为style="?android:attr/progressBarStyleHorizontal"</p>
<p> </p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="452" data-height="136"><img src="https://upload-images.jianshu.io/upload_images/3030704-3435c67929f75172.png?imageMogr2/auto-orient/strip|imageView2/2/w/452/format/webp"></div>
</div>
<div class="image-caption">image.png</div>
</div>
<p> </p>
<p>max属性指定进度条总进度值,progress设置当前进度值,也可以说是初始进度值</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"> <span class="token comment">//xml中
<span class="token operator"><ProgressBar
android<span class="token punctuation">:id<span class="token operator">=<span class="token string">"@+id/progress_bar_h"
style<span class="token operator">=<span class="token string">"?android:attr/progressBarStyleHorizontal"
android<span class="token punctuation">:layout_width<span class="token operator">=<span class="token string">"85dp"
android<span class="token punctuation">:layout_height<span class="token operator">=<span class="token string">"10dp"
android<span class="token punctuation">:layout_gravity<span class="token operator">=<span class="token string">"center"
android<span class="token punctuation">:max<span class="token operator">=<span class="token string">"100"
android<span class="token punctuation">:progress<span class="token operator">=<span class="token string">"50"
<span class="token operator">/<span class="token operator">>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<h3>设进度条背景</h3>
<p>系统自带的进度条的颜色比较单调,实际开发中使用较少,可以自定义进度条背景,新建一个progressbar_bg.xml文件</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-xml"><code class="language-xml"> <span class="token prolog"><?xml version="1.0" encoding="UTF-8"?>
<span class="token tag"><span class="token tag"><span class="token punctuation"><layer-list <span class="token attr-name"><span class="token namespace">xmlns:android<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"http://schemas.android.com/apk/res/android<span class="token punctuation">"<span class="token punctuation">>
<span class="token comment"><!--设置背景色-->
<span class="token tag"><span class="token tag"><span class="token punctuation"><item <span class="token attr-name"><span class="token namespace">android:id<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"@android:id/background<span class="token punctuation">"
<span class="token attr-name"><span class="token namespace">android:drawable<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"@mipmap/feed_grow_progress_bar<span class="token punctuation">"<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"></item<span class="token punctuation">>
<span class="token comment"><!--设置进度条颜色-->
<span class="token tag"><span class="token tag"><span class="token punctuation"><item <span class="token attr-name"><span class="token namespace">android:id<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"@android:id/progress<span class="token punctuation">"<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"><clip<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"><shape<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"><gradient
<span class="token attr-name"><span class="token namespace">android:endColor<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"#fff000<span class="token punctuation">"
<span class="token attr-name"><span class="token namespace">android:startColor<span class="token attr-value"><span class="token punctuation">=<span class="token punctuation">"#fff000<span class="token punctuation">" <span class="token punctuation">/>
<span class="token tag"><span class="token tag"><span class="token punctuation"></shape<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"></clip<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"></item<span class="token punctuation">>
<span class="token tag"><span class="token tag"><span class="token punctuation"></layer-list<span class="token punctuation">>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>gradient可以设置进度条的渐变色, android:endColor和 android:startColor可以设置渐变开始和结束的颜色。定义完成以后,便可以使用</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-objectivec"><code class="language-objectivec"><span class="token operator"><ProgressBar
android<span class="token punctuation">:id<span class="token operator">=<span class="token string">"@+id/progress_bar_healthy"
style<span class="token operator">=<span class="token string">"?android:attr/progressBarStyleHorizontal"
android<span class="token punctuation">:layout_width<span class="token operator">=<span class="token string">"85dp"
android<span class="token punctuation">:layout_height<span class="token operator">=<span class="token string">"10dp"
android<span class="token punctuation">:layout_marginTop<span class="token operator">=<span class="token string">"20dp"
android<span class="token punctuation">:layout_gravity<span class="token operator">=<span class="token string">"center"
android<span class="token punctuation">:max<span class="token operator">=<span class="token string">"100"
android<span class="token punctuation">:progress<span class="token operator">=<span class="token string">"50"
android<span class="token punctuation">:progressDrawable<span class="token operator">=<span class="token string">"@drawable/progressbar_bg"
<span class="token operator">/<span class="token operator">>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<p>效果图,这里设置了黄色矩形背景,及黄色进度条</p>
<p> </p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="356" data-height="85"><img src="https://upload-images.jianshu.io/upload_images/3030704-dfecccca6e55829e.png?imageMogr2/auto-orient/strip|imageView2/2/w/356/format/webp"></div>
</div>
<div class="image-caption">image.png</div>
</div>
<h3>动态设置</h3>
<p>在音乐进度,网络下载时,需动态加载进度条,默认情况下,设置进度条,使用setProgress()即可。但有时除了动态设置进度,仍需要动态设置进度条颜色</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-cpp"><code class="language-cpp"><span class="token keyword">private <span class="token keyword">void <span class="token function">setElectircProgress<span class="token punctuation">(<span class="token keyword">int i<span class="token punctuation">, <span class="token keyword">int color<span class="token punctuation">) <span class="token punctuation">{
ClipDrawable drawable <span class="token operator">= <span class="token keyword">new <span class="token function">ClipDrawable<span class="token punctuation">(<span class="token keyword">new <span class="token function">ColorDrawable<span class="token punctuation">(color<span class="token punctuation">)<span class="token punctuation">, Gravity<span class="token punctuation">.LEFT<span class="token punctuation">, ClipDrawable<span class="token punctuation">.HORIZONTAL<span class="token punctuation">)<span class="token punctuation">;
progressBarElectric<span class="token punctuation">.<span class="token function">setProgressDrawable<span class="token punctuation">(drawable<span class="token punctuation">)<span class="token punctuation">;
progressBarElectric<span class="token punctuation">.<span class="token function">setProgress<span class="token punctuation">(i<span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div>
<h1>音乐播放实例</h1>
<p>通过MediaPlayer 播放音乐并获取进度,设置进度</p>
<p> </p>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill"> </div>
<div class="image-view" data-width="307" data-height="66"><img src="https://upload-images.jianshu.io/upload_images/3030704-7ff3596851ed4376.png?imageMogr2/auto-orient/strip|imageView2/2/w/307/format/webp"></div>
</div>
<div class="image-caption">image.png</div>
</div>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<pre class="line-numberslanguage-java"><code class="language-java">musicProgressBar <span class="token operator">= <span class="token punctuation">(<span class="token class-name">ProgressBar<span class="token punctuation">) <span class="token function">findViewById<span class="token punctuation">(<span class="token class-name">R<span class="token punctuation">.id<span class="token punctuation">.progress_bar_music<span class="token punctuation">)<span class="token punctuation">;
<span class="token keyword">if <span class="token punctuation">(mPlayer <span class="token operator">!= <span class="token keyword">null<span class="token punctuation">) <span class="token punctuation">{
mPlayer<span class="token punctuation">.<span class="token function">release<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
mPlayer <span class="token operator">= <span class="token keyword">null<span class="token punctuation">;
<span class="token punctuation">}
mPlayer <span class="token operator">= <span class="token class-name">MediaPlayer<span class="token punctuation">.<span class="token function">create<span class="token punctuation">(<span class="token keyword">this<span class="token punctuation">, <span class="token class-name">R<span class="token punctuation">.raw<span class="token punctuation">.summer<span class="token punctuation">)<span class="token punctuation">;
mPlayer<span class="token punctuation">.<span class="token function">start<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
musicProgressBar<span class="token punctuation">.<span class="token function">setMax<span class="token punctuation">(mPlayer<span class="token punctuation">.<span class="token function">getDuration<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;
<span class="token keyword">if <span class="token punctuation">(timer <span class="token operator">!= <span class="token keyword">null<span class="token punctuation">) <span class="token punctuation">{
timer <span class="token operator">= <span class="token keyword">null<span class="token punctuation">;
timerTask <span class="token operator">= <span class="token keyword">null<span class="token punctuation">;
<span class="token punctuation">}
timer <span class="token operator">= <span class="token keyword">new <span class="token class-name">Timer<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;
timerTask <span class="token operator">= <span class="token keyword">new <span class="token class-name">TimerTask<span class="token punctuation">(<span class="token punctuation">) <span class="token punctuation">{
<span class="token annotation punctuation">@Override
<span class="token keyword">public <span class="token keyword">void <span class="token function">run<span class="token punctuation">(<span class="token punctuation">) <span class="token punctuation">{
<span class="token keyword">if <span class="token punctuation">(mPlayer <span class="token operator">!= <span class="token keyword">null<span class="token punctuation">) <span class="token punctuation">{
<span class="token keyword">if <span class="token punctuation">(mPlayer<span class="token punctuation">.<span class="token function">isPlaying<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">) <span class="token punctuation">{
<span class="token function">runOnUiThread<span class="token punctuation">(<span class="token keyword">new <span class="token class-name">Runnable<span class="token punctuation">(<span class="token punctuation">) <span class="token punctuation">{
<span class="token annotation punctuation">@Override
<span class="token keyword">public <span class="token keyword">void <span class="token function">run<span class="token punctuation">(<span class="token punctuation">) <span class="token punctuation">{
musicProgressBar<span class="token punctuation">.<span class="token function">setProgress<span class="token punctuation">(mPlayer<span class="token punctuation">.<span class="token function">getCurrentPosition<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}
<span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;
<span class="token punctuation">}
<span class="token punctuation">}
<span class="token punctuation">}
<span class="token punctuation">}<span class="token punctuation">;
timer<span class="token punctuation">.<span class="token function">schedule<span class="token punctuation">(timerTask<span class="token punctuation">, <span class="token number">0<span class="token punctuation">, <span class="token number">1000<span class="token punctuation">)<span class="token punctuation">;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
</div><br><br>
来源:https://www.cnblogs.com/xgjblog/p/14101896.html 感谢楼主的分享,这篇 ProgressBar 的教程写得很详细,从默认圆形到横向进度条,再到自定义背景和音乐播放实例都有涉及,对新老手都挺有帮助的!
稍微补充一点在实际开发中可能会碰到的小细节:
- 动态设置进度时,如果是在子线程更新 UI,记得要切换到主线程,楼主在音乐播放示例里用 `runOnUiThread` 处理了,这个习惯很好,不然容易报 `CalledFromWrongThreadException`。
- 自定义进度条背景时,除了 `layer-list` 和 `clip`,还可以用 `scale` 标签来做分段式效果,比如电池电量那种分段显示。
- 如果进度条需要支持拖拽(比如音乐播放器可拖动改变进度),可以结合 `SeekBar` 实现,它继承自 `ProgressBar`,自带滑块,用起来更直接。
想问一下楼主,在音乐播放实例里,进度每秒更新一次,如果歌曲比较长,有没有考虑过用更平滑的更新方式,比如根据歌曲时长动态调整更新间隔,或者直接用 `Handler` 发送延迟消息来避免 Timer 可能带来的内存泄漏问题?
期待楼主后续更多 Android 开发的干货分享! 楼主这篇教程太实用了!ProgressBar确实是日常开发里高频用到的控件,尤其是自定义样式和进度同步这块,之前我也踩过不少坑。补充几个小经验吧:
[]如果是做长列表里的进度条,建议用RecyclerView的ViewHolder复用机制,避免频繁findViewById导致卡顿。
[]自定义drawable时,注意padding和clip区域的匹配,不然进度条看起来会偏或者留白。
[*]对于需要精确控制进度的场景,可以试试结合ValueAnimator做平滑过渡动画,用户体验会好很多。
感谢分享,期待楼主更多Android实战干货!顶一个!
頁:
[1]