Android ProgressBar setProgressDrawable 设置无效问题

来源:互联网 发布:电话变声软件男变女 编辑:程序博客网 时间:2024/05/16 23:56

ProgressBar的背景设置xml时可以使用,但代码setProgressDrawable设置则无效。
layer-list如下:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" >    <item        android:id="@+android:id/background"        android:drawable="@drawable/icon_love">    </item>    <item        android:id="@+android:id/secondaryProgress"        android:drawable="@drawable/icon_love">    </item>    <item        android:id="@+android:id/progress"        android:drawable="@drawable/icon_love">    </item></layer-list>

在代码设置无效:

ProgressBar.setProgressDrawable(getResources().getDrawable(R.drawable.ratingbar_drawable_heart));

查看源码发现:

    public void setProgressDrawable(Drawable d) {        boolean needUpdate;        if (mProgressDrawable != null && d != mProgressDrawable) {            mProgressDrawable.setCallback(null);            needUpdate = true;        } else {            needUpdate = false;        }        if (d != null) {            d.setCallback(this);            // Make sure the ProgressBar is always tall enough            int drawableHeight = d.getMinimumHeight();            if (mMaxHeight < drawableHeight) {                mMaxHeight = drawableHeight;                requestLayout();            }        }        mProgressDrawable = d;            ...

导致相当于换了背景一样(本来有三颗星的):
这里写图片描述

再发现sdk版本21有setProgressDrawableTiled方法可以解决,最版本怎么处理?原来setProgressDrawableTiled有个方法tileify:

    public void setProgressDrawableTiled(Drawable d) {        if (d != null) {            d = tileify(d, false);        }        setProgressDrawable(d);    }

是否底版本也有,看了一下14版本的sdk,也有这个私有方法!

    private Drawable tileify(Drawable drawable, boolean clip) {        if (drawable instanceof LayerDrawable) {            LayerDrawable background = (LayerDrawable) drawable;            final int N = background.getNumberOfLayers();            Drawable[] outDrawables = new Drawable[N];            for (int i = 0; i < N; i++) {                int id = background.getId(i);                outDrawables[i] = tileify(background.getDrawable(i),                        (id == R.id.progress || id == R.id.secondaryProgress));            }            LayerDrawable newBg = new LayerDrawable(outDrawables);            for (int i = 0; i < N; i++) {                newBg.setId(i, background.getId(i));            }            return newBg;            ...

那解决方法可想而知,用java反射调用此方法:

    @SuppressLint("NewApi")    public static void setProgressDrawable(@NonNull ProgressBar bar, @DrawableRes int resId) {        Drawable layerDrawable = bar.getResources().getDrawable(resId);        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {            Drawable d = getMethod("tileify", bar, new Object[] { layerDrawable, false });            bar.setProgressDrawable(d);        } else {            bar.setProgressDrawableTiled(layerDrawable);        }    }    private static Drawable getMethod(String methodName, Object o, Object[] paras) {        Drawable newDrawable = null;        try {            Class<?> c[] = new Class[2];            c[0] = Drawable.class;            c[1] = boolean.class;            Method method = ProgressBar.class.getDeclaredMethod(methodName, c);            method.setAccessible(true);            newDrawable = (Drawable) method.invoke(o, paras);        } catch (Exception ex) {            ex.printStackTrace();        }        return newDrawable;    }

最后调用此方法
setProgressDrawable(bar, R.drawable.ratingbar_drawable_heart);
解决底版本代码设置问题:
这里写图片描述

0 0
原创粉丝点击