Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android TransitionDrawable with multiple items

Tags:

java

android

I want to create a Button in Android with a text, and a background image. The background image should crossfade every X time.

I have this working using a TransitionDrawable with 2 images.

But I can't get this to work with more than 2 images.

What I have :

In Java code I create a Button and set a background (which is a TransitionDrawable defined in XML). And I start the transition.

final Button b = new Button(getApplicationContext());
b.setTextColor(getResources().getColor(R.color.white));
b.setText("Some text");
b.setBackgroundDrawable(getResources().getDrawable(R.drawable.tile));
StateListDrawable background = (StateListDrawable) b.getBackground();
TransitionDrawable td = (TransitionDrawable) background.getCurrent();
td.startTransition(2000);

In XML I define in tile.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#449def" />
        </shape>
    </item>
    <item android:drawable="@drawable/transition">
        <shape>
            <solid
                android:color="#0000ff" />
        </shape>
    </item>
</selector> 

And finally a transition.xml

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android"     android:oneshot="false">
  <item android:drawable="@drawable/desert"/> 
  <item android:drawable="@drawable/hydrangeas" /> 
  <item android:drawable="@drawable/jellyfish" /> 
</transition> 

Now the effect is that when I start the app the desert image is shown. This image crossfades to the hydrangeas image as it should. But the jellyfish image is never shown.

In the doc for TransitionDrawables it is stated that you can specify more than 2 drawables but I can't get this to work.

I also tried this without any XML but in pure JAVA but this gave exactly the same problem :-(

like image 235
Knarf Avatar asked Mar 27 '13 10:03

Knarf


4 Answers

You can do it by using a handler

mAnimateImage is your button

int DrawableImage[] = {R.drawable.back_red, R.drawable.back_green, R.drawable.back_purple};

final Handler handler = new Handler();
    final int[] i = {0};
    final int[] j = {1};
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Resources res = getApplicationContext().getResources();
                    TransitionDrawable out = new TransitionDrawable(new Drawable[]{res.getDrawable(DrawableImage[i[0]]), res.getDrawable(DrawableImage[j[0]])});
                    out.setCrossFadeEnabled(true);
                    mAnimateImage.setBackgroundDrawable(out);
                    out.startTransition(4000);
                    i[0]++;
                    j[0]++;
                    if (j[0] == DrawableImage.length) {
                        j[0] = 0;
                    }
                    if (i[0] == DrawableImage.length) {
                        i[0] = 0;
                    }
                    handler.postDelayed(this, 8000);
                }
            });
        }
    }, 0);
like image 129
Om Prakash Agrahari Avatar answered Nov 18 '22 15:11

Om Prakash Agrahari


According to the official documentation, TransitionDrawable can only cross-fade among 2 layers, quoting from the official android reference.

An extension of LayerDrawables that is intended to cross-fade between the first and second layer. To start the transition, call startTransition(int). To display just the first layer, call resetTransition().

If you don't read it carefully, since it extends LayerDrawables, which can have multiple layers, one may expect that you could cross-fade from N layers. But it is very clear, startTransition shows the second layer, resetTransition shows the first.

I suggest you do your own implementation for multiple transitions. What I'd do is to have 2 images and animate them. You may need to set the drawables by hand, but it should be a quite simple piece of code.

like image 30
shalafi Avatar answered Nov 18 '22 15:11

shalafi


in appendix operating time you can dynamically change pictures

Use td.setDrawableByLayerId(td.getId(1), drawable) on your TransitionDrawable

TransitionDrawable transitionDrawable = (TransitionDrawable) myImage
                            .getDrawable();
transitionDrawable.setDrawableByLayerId(transitionDrawable.getId(1), getResources()
                            .getDrawable(R.drawable.c));
like image 24
Sergei S Avatar answered Nov 18 '22 16:11

Sergei S


You can only transition maximum two images with TransitionDrawable. To work with more than two images you can extend LayerDrawable and implement your own TransitionDrawable.

Here's the ready implementation of custom TransitionDrawable to work with more than two images.

You can see the complete sample along with the gif demo here on Github.

like image 1
Yogesh Umesh Vaity Avatar answered Nov 18 '22 16:11

Yogesh Umesh Vaity