开发者

android UI: TransitionDrawable

What's the intended way to use a TransitionDrawable in code? Any examples?

I made a small test app to lay down some context:

public class SkeletonActivity extends Activity {
    private Button b;
    private ImageView iv;
    private TransitionDrawable transition;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Inflate our UI from its XML layout description.
        setContentView(R.layout.skeleton_activity);

        // Hook up button presses to the appropriate event handler.
        b = ((Button) findViewById(R.id.button));
        b.setOnClickListener(mButtonListener);
        iv = ((ImageView) findViewById(R.id.image));

        //XML-based code
        transition = (TransitionDrawable)getResources().getDrawable(R.drawable.trans).mutate();
        transition.setDrawableByLayerId(transition.getId(0), getResources().getDrawable(R.drawable.trans3));
        transition.setDrawableByLayerId(transition.getId(1), getResources().getDrawable(R.drawable.trans4));

        //Pure programmatic code
        transition = new TransitionDrawable(new Drawable[] {getResources().getDrawable(R.drawable.trans3), getResources().getDrawable(R.drawable.trans4)});

        transition.setCrossFadeEnabled(true);
    }

    OnClickListener mButtonListener = new OnClickListener() {
        public void onClick(View v) {
            iv.setImageDrawable(transition);
            transition.startTransition(5000);
        }
    };
}

and my TransitionDrawable xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/trans1" />
    <item android:drawable="@drawable/trans2" />
</transition>

Let's first start with the XML-based code part (so that means comment out the Pure programmatic code line).

If you run this code and press the button, then you see he image change from trans1 to trans4, instead of from trans3. Why isn't the initial drawable replaced?

The whole setDrawableByLayerId() method is confusing. In the constructor you'd specify a list of Drawables that goes into a LayerDrawable. I suppose these are what is referred to as indexes. Then what is an id if it is not such an index?

I tried adding android:id attributes to the "item" tags. While this code builds, it does not run. So id is not this id, that you'd normally have.

Perhaps it is the resId of the current drawable in that position? That doesn't seem either.

Id seems to be just some number (maybe it matters in a LayerDrawable) that can be set with setId(index, id) and gotten with getId(index). By default no ids are assigned. And you can reserve none for layers that have not been added yet. In my code both getId() calls return -1, which is why when using setDrawableByLayerId(-1, ...) only the last one sticks. Indeed commenting out the last line gives different behavior, giving a transition from trans1 to trans3.

How can I change the first drawable layer? I have to add the following code before the setDrawableByLayerId(). Even when I don't use 50 or 51 anywhere. This makes it go from trans3 to trans4.

transition.setId(0, 50);
transition.setId(1, 51);

What is wrong about my concepts that I have to make it this complicated to get it to work?

What I actually wanted to do in my real app was not use any xml code, I see no use fo开发者_如何学运维r it. I'd also like to first add in the first layer, and only later, after construction, put in the second layer, but we'll continue with that later.

Let's try the pure programmatic code. It is equivalent. In fact it puts in the right Drawables right away.

Now, in this sample app it gives the same result. However, in my app (of which the relevant code is too complex to post here), I still have a problem:

If I try with preprogrammed Drawables from an xml-specified transition, I get that getResources().getDrawable(R.drawable.trans) the second time returns null:

12-30 21:35:32.970: ERROR/AndroidRuntime(7457): java.lang.NullPointerException
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.LayerDrawable$LayerState.<init>(LayerDrawable.java:581)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable$TransitionState.<init>(TransitionDrawable.java:235)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.createConstantState(TransitionDrawable.java:99)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.LayerDrawable.<init>(LayerDrawable.java:94)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.<init>(TransitionDrawable.java:90)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable.<init>(TransitionDrawable.java:39)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.graphics.drawable.TransitionDrawable$TransitionState.newDrawable(TransitionDrawable.java:245)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.getCachedDrawable(Resources.java:1753)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.loadDrawable(Resources.java:1664)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at android.content.res.Resources.getDrawable(Resources.java:581)
12-30 21:35:32.970: ERROR/AndroidRuntime(7457):     at net.lp.collectionista.ui.views.CoverView.updateCover(CoverView.java:78)

What am I missing here? Something with missing mutate()?

I mentioned I'd also like to set the layers in two steps, and fully in code. Meaning I'd first have to do

transition = new TransitionDrawable(new Drawable[] {<1>});

with passing in only one layer. However I cannot do setId() on a new layer, so I can't add a new layer later on (although reading the documentation for setDrawableByLayerId() would lead you to believe you could).

Passing in a second layer straight away, by means of an array of 2 with second element null, is punished, so I'll just pass in the same drawable as the first layer then.

Anything I've been missing here and could have done easier?


I recommend simply creating a new TransitionDrawable instead of "raping" your old one. I do that all the time:

Here is a code snippet of mine that creates a TransitionDrawable for the sharing button:

private TransitionDrawable createIconTransition( SharingStates layer1, SharingStates layer2 )
{
    Resources res = getContext().getResources();

    TransitionDrawable out = new TransitionDrawable( new Drawable[] { res.getDrawable( layer1.mIconId ), res.getDrawable( layer2.mIconId )} );
    out.setCrossFadeEnabled( true );

    return out;

}

And then call:

mImageView.setImageDrawable( mTransitionDrawable );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜