我想制作一个确定的圆形进度条(意思是 android:indeterminate =" false" ),所以我搜索了互联网并找到了Romain Guy的简短回答,here。
所以我抓住了代码并在示例项目中使用它:
(部分)布局文件:
<ProgressBar
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@color/backColor"
android:indeterminate="false"
android:indeterminateOnly="false"
android:max="100"
android:progress="33"
android:progressDrawable="@drawable/progress" />
抽拉/ progress.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- <item android:drawable="@drawable/progress_circular_background"/> -->
<item>
<shape
android:innerRadiusRatio="3.4"
android:shape="ring"
android:thicknessRatio="6.0" >
<gradient
android:endColor="#ffffffff"
android:startColor="#ff000000"
android:type="sweep"
android:useLevel="true" />
</shape>
</item>
<item>
<rotate
android:drawable="@drawable/progress_particle"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
</item>
</layer-list>
屏幕截图(不完全是当前代码):
它工作正常,但我不明白它是如何工作的。
进度条如何知道在drawables上究竟要改变什么,以及如何改变?
例如,它如何知道如何从右边的0度而不是其他地方获取戒指形状?
是否可以自定义它的工作方式?
答案 0 :(得分:8)
ProgressBar通过更改关联的drawable的级别来工作。在doRefreshProgress()
:
final int level = (int) (scale * MAX_LEVEL);
(progressDrawable != null ? progressDrawable : d).setLevel(level);
Drawable's level基本上是一个整数,对于不同类型的Drawable
子类可能有不同的含义。
这允许drawable基于连续变化其图像 控制器,例如显示进度或音量级别。
如果级别中的此更改导致Drawable的外观发生更改(因此需要无效),则返回true,否则返回false。
特别是,GradientDrawable
(带useLevel="true"
,例如这个)使用级别值来知道应该绘制哪个部分的drawable。例如,对于从左到右的线性渐变,矩形计算如下:
final float level = st.mUseLevel ? (float) getLevel() / 10000.0f : 1.0f;
x0 = r.left; y0 = r.top;
x1 = level * r.right; y1 = y0;
对于 ring 渐变(例如此渐变),该等级确定应绘制总360度角的哪个部分:
float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f;
简而言之,当调用setProgress()
方法时,此值会更改,并且循环将逐渐填充。
对于RotateDrawable
,它使用相同的机制来围绕其中心旋转progress_particle
位图(它只是一个90度白点的透明正方形):
mState.mCurrentDegrees = mState.mFromDegrees +
(mState.mToDegrees - mState.mFromDegrees) * ((float) level / MAX_LEVEL);
最后,关于“它如何知道如何仅从右边的0度采取环形部分,这只是一个常规问题。 Ring GradientDrawables从右侧开始。环路径计算中的第一行是:
// inner top
ringPath.moveTo(x + radius, y);
// outer top
ringPath.lineTo(x + radius + thickness, y);