探究
假设我们在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 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:
<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那个圆形默认样式为不确定(且不允许设置为确定进度)
具体原因就不深究了,有兴趣的读者可以研究研究,在评论区回复告知我 ?