带有图像的自定义进度条或带有 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();