views:

32

answers:

1

Hi,

I am trying to store drawables in a static SoftReferenceMap for a ListView containing progress-bars in every row. Every row has a different progress, but when I set it through setProgress(int) all rows get affected.

I tried doing mDrawable.mutate().setLevel(progress*10000/max), but it still doesn't work.

public void setProgres(int status, int progress, int max) {

        Drawable d = getDrawable(status);

        switch (status) {
        case RED_INDETERMINATE:
            setIndeterminateDrawable(d);
            setIndeterminate(true);
            break;
        case YELLOW:
            d.mutate().setLevel((int) (progress * 10000 / max));
        case GREEN:
        case BLUE:
            setProgressDrawable(d);
            break;

        default:
            throw new IllegalArgumentException(
                    "Invalid Status setting for ArtooProgressBar: " + status);
        }

        getProgressDrawable().invalidateSelf();
        super.invalidate();
    }

    private Drawable getDrawable(int status) {

        SoftReference<Drawable> ref = sDrawableMaps.get("" + status);

        if (ref != null && ref.get() != null)
            return ref.get();

        Drawable d;

        switch (status) {
        case RED_INDETERMINATE:
            d = getResources().getDrawable(
                    R.drawable.progress_bar_indeterminate);
            d = tileifyIndeterminate(d);
            break;
        case YELLOW:
            // d = yellow;
            d = getResources().getDrawable(
                    R.drawable.progress_bar_determinate_yellow);
            break;
        case GREEN:
            d = getResources().getDrawable(
                    R.drawable.progress_bar_determinate_green);
            d.setLevel(10000);
            break;
        case BLUE:
            d = getResources().getDrawable(
                    R.drawable.progress_bar_determinate_blue);
            d.setLevel(10000);
            break;

        default:
            throw new IllegalArgumentException(
                    "Invalid Status setting for ArtooProgressBar: " + status);
        }

        if (d != null)
            sDrawableMaps.put("" + status, new SoftReference<Drawable>(d));

        d.invalidateSelf();
        return d;

    }

What am I missing?

Thanks

A: 

It looks like you are sharing the same Drawable instance across multiple views. Basically, don't do that. Why are you doing this sDrawableMaps cache thing instead of just calling Resources.getDrawable() for each Drawable you need? It is likely the cause of trouble.

Also your use of mutate() is not going to do what you think -- if the Drawable is not already mutable, then this returns a new Drawable instance which you then modify and nobody actually sees. If it is already mutable, it does return the same instance, but in that case there was no reason to call mutate() on it.

hackbod
I am using a cache because, you can only create drawables in the onCreate() I believe and thus they vanish when I scroll up/down my list. How do you make the drawable mutable - d.mutate() is not working.
Sameer Segal
You can create a drawable whenever you want. Honestly, get rid of the cache and just call Resources.getDrawable() when you need a drawable. And you have no need for "mutate()" for what you are doing -- getDrawable() returns a Drawable that is unique enough to allow you to call setLevel() etc on it. mutate() is for something different than what you are trying to do. You are ending up with the exact same Drawable object being used by multiple UI elements. You just need to fix that.
hackbod