带有图像的自定义进度条或带有 clipdrawable 的图像视图
Custom progress bar with images or Image view with clipdrawable
我一直在寻找关于自定义进度条的教程,我发现的 95% 的内容是如何使用颜色和渐变而不是图像(基本上是顶部有图像的空栏图像或完整栏)进行自定义。当我尝试将图像用于进度条时,尺寸错误(包装内容无法正常工作并且被截断了一半)。
我能够使用带有 clipdrawble 和级别设置的图像来成功制作图像条。
SOOO,ProgressBar 的图像用于其 background/progress 不受欢迎,我应该改用 imageview 吗?
关键是要确保 ProgressBar
考虑到自定义绘图的尺寸。一种方法是覆盖 onMeasure
。这是您的自定义 class 的 onMeasure
实现的粗略草图(将其与 ProgressBar
的实现进行比较 - 您会注意到细微的变化):
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
// the super's onMeasure method ignores the dimensions of the custom progress drawable
// if they are greater than a specified height & width (mMaxHeight & mMaxWidth). It simply uses those
// default dimensions for the drawable, consequently resizing them; which is not suitable for larger drawables.
// So, it is necessary to override this method to allow the ProgressBar to account for the drawable's original
// dimensions and draw the image/drawable accordingly.
Drawable d = getProgressDrawable();
int dw = 0;
int dh = 0;
if (d != null) {
dw = d.getIntrinsicWidth();
dh = d.getIntrinsicHeight();
}
int[] state = getDrawableState();
if(mProgressDrawable != null && mProgressDrawable.isStateful())
mProgressDrawable.setState(state);
dw += getPaddingLeft() + getPaddingRight();
dh += getPaddingTop() + getPaddingBottom();
setMeasuredDimension(resolveSize(dw, widthMeasureSpec), resolveSize(dh, heightMeasureSpec));
}
然后您可以将空白栏设置为自定义 ProgressBar
的背景,就像您通常为视图所做的那样 - android:background="@drawable/empty_bar"
下一部分是设置 progressDrawable
,为此您必须使用 <layer-list>
,因为我们要与进度条的可绘制结构紧密匹配 (default 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>
<solid android:color="#00000000"/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom"
android:drawable="@drawable/full_bar">
</clip>
</item>
</layer-list>
最后,要为进度条设置动画,您可以使用 ObjectAnimator
:
final ObjectAnimator animator = ObjectAnimator
.ofInt(progressBar, "progress", 0, 100)
.setDuration(2000);
animator.start();
我一直在寻找关于自定义进度条的教程,我发现的 95% 的内容是如何使用颜色和渐变而不是图像(基本上是顶部有图像的空栏图像或完整栏)进行自定义。当我尝试将图像用于进度条时,尺寸错误(包装内容无法正常工作并且被截断了一半)。
我能够使用带有 clipdrawble 和级别设置的图像来成功制作图像条。
SOOO,ProgressBar 的图像用于其 background/progress 不受欢迎,我应该改用 imageview 吗?
关键是要确保 ProgressBar
考虑到自定义绘图的尺寸。一种方法是覆盖 onMeasure
。这是您的自定义 class 的 onMeasure
实现的粗略草图(将其与 ProgressBar
的实现进行比较 - 您会注意到细微的变化):
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
// the super's onMeasure method ignores the dimensions of the custom progress drawable
// if they are greater than a specified height & width (mMaxHeight & mMaxWidth). It simply uses those
// default dimensions for the drawable, consequently resizing them; which is not suitable for larger drawables.
// So, it is necessary to override this method to allow the ProgressBar to account for the drawable's original
// dimensions and draw the image/drawable accordingly.
Drawable d = getProgressDrawable();
int dw = 0;
int dh = 0;
if (d != null) {
dw = d.getIntrinsicWidth();
dh = d.getIntrinsicHeight();
}
int[] state = getDrawableState();
if(mProgressDrawable != null && mProgressDrawable.isStateful())
mProgressDrawable.setState(state);
dw += getPaddingLeft() + getPaddingRight();
dh += getPaddingTop() + getPaddingBottom();
setMeasuredDimension(resolveSize(dw, widthMeasureSpec), resolveSize(dh, heightMeasureSpec));
}
然后您可以将空白栏设置为自定义 ProgressBar
的背景,就像您通常为视图所做的那样 - android:background="@drawable/empty_bar"
下一部分是设置 progressDrawable
,为此您必须使用 <layer-list>
,因为我们要与进度条的可绘制结构紧密匹配 (default 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>
<solid android:color="#00000000"/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity="bottom"
android:drawable="@drawable/full_bar">
</clip>
</item>
</layer-list>
最后,要为进度条设置动画,您可以使用 ObjectAnimator
:
final ObjectAnimator animator = ObjectAnimator
.ofInt(progressBar, "progress", 0, 100)
.setDuration(2000);
animator.start();