之前遇到一个问题,发现Android里的圆形进度条无法固定一个进度,记录一下解决方法
探究
假设我们在xml中这样写:
xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".page.home.HomeFragment">
<ProgressBar
android:indeterminate="false"
android:id="@+id/pbStorage"
android:progress="60"
android:max="100"
android:layout_width="100dp"
android:layout_height="100dp"/>
</FrameLayout>
按照预料的,上面的我们的进度条应该是圆形,且设置indeterminate属性,应该是固定了进度,但实际效果如下:
进度条是一直在转动的
之后通过翻阅官方的文档发现,ProgressBar虽然提供了一个圆形和水平进度条的样式,但是圆形的样式它不支持确定进度
我们可以打开其内置的theme来找到答案,如下的2个截图
解决
那么我们应该如何解决?很简单,我们可以从参考上面的水平进度条,设置对应的drawable属性即可解决
progressDrawable
:用于设置ProgressBar
的进度条样式。可以通过指定一个drawable资源来定义进度条的外观。通常用于显示确定的进度,即进度会从0%到100%之间变化。indeterminateDrawable
:用于设置ProgressBar
在不确定进度时的样式。当ProgressBar
处于不确定进度(indeterminate)时,进度条会显示一个循环动画,而不是固定的进度。通过指定一个drawable资源,可以定义不确定进度时的样式。
当我们设置Progressbar的 indeterminate
属性的时候为true,则ProgressBar使用 indeterminateDrawable
这个外观,否则则使用 progressDrawable
这个外观
于是我们可以自定义一个圆形的外观drawable,名为 progress_bar_green.xml
(放在drawable资源目录下),代码如下:
xml
<?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
android:innerRadiusRatio="3.5"
android:shape="ring"
android:useLevel="false"
android:type="sweep"
android:thicknessRatio="12.0">
<!-- 进度条默认底色 -->
<solid android:color="#f2f2f2"/>
</shape>
</item>
<item android:id="@android:id/progress">
<rotate
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="-90"
android:toDegrees="-90">
<shape
android:innerRadiusRatio="3.5"
android:shape="ring"
android:angle="0"
android:type="sweep"
android:thicknessRatio="12.0">
<!-- 进度条颜色 -->
<solid android:color="#33cf59"/>
</shape>
</rotate>
</item>
</layer-list>
PS: 如果想要进度条的圆环宽度变小,可以将
thicknessRatio
属性调大,如果2个thicknessRatio的数值不一致,则是出现下面这种效果,看需求自行调整
之后xml布局里使用此drawable:
diff
<ProgressBar
+ style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+ android:progressDrawable="@drawable/progress_bar_green"
+ android:indeterminate="false"
android:id="@+id/pbStorage"
android:progress="60"
android:max="100"
android:layout_width="100dp"
android:layout_height="100dp"/>
这里发现必须要使用 Widget.AppCompat.ProgressBar.Horizontal
这个样式才能使我们的progressDrawable属性生效,猜测是ProgressBar内部或者Android系统内部应该是固定ProgressBar那个圆形默认样式为不确定(且不允许设置为确定进度)
具体原因就不深究了,有兴趣的读者可以研究研究,在评论区回复告知我 😄