Olek
Olek

Reputation: 165

How to make continuously running TransitionDrawable animation in Android?

I'm trying to make an animated logo. It consists of two static images.

I would to like to achieve a cross-fading effect.

I've done it with the use of TransitionDrawable, set the crossFadeEnabled and everything looks nice.

The thing is that I need to be running in circle. How can it be achieved ?

<transition xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/image_expand">
  <item android:drawable="@drawable/image_collapse">
</transition>

Resources res = mContext.getResources();
TransitionDrawable transition = (TransitionDrawable) res.getDrawable(R.drawable.expand_collapse);
ImageView image = (ImageView) findViewById(R.id.toggle_image);
image.setImageDrawable(transition);

This the code from google which runs perfectly. The most importantn thing is that in needs to work under Android 1.6.

Upvotes: 5

Views: 6412

Answers (2)

Albert
Albert

Reputation: 21

I managed to get the transition drawable to work via a handler method that reverses direction after the transition from drawable1 to drawable2. In my XML's :

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android"  >

    <item android:drawable="@drawable/background_animation1"/>
    <item android:drawable="@drawable/background_animation2"/>

</transition>

The drawables are gradients :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
     <corners android:topLeftRadius = "10dp" android:topRightRadius="10dp" android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/>
    
    <gradient
        android:startColor="#d200ff" 
        android:centerColor="#4e00ff"
        android:endColor="#006cff"/>

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <size android:width="900dp" android:height="500dp"/>
    <corners android:topLeftRadius = "10dp" android:topRightRadius="10dp" android:bottomLeftRadius="10dp" android:bottomRightRadius="10dp"/>
    <gradient
        android:startColor="#006cff" 
        android:centerColor="#ff6600"
        android:endColor="#d200ff"/>

</shape>

In my initialisation code :

trans = (TransitionDrawable) getResources().getDrawable(R.drawable.transition);
		trans.setCrossFadeEnabled(true);
		backgroundimage.setImageDrawable(trans);

....

handlechange();

And the most important bit in the handler code; note the flag that is running globally. I got this running on Gingerbread and Kitkat;

void handlechange1()
	{
		Handler hand = new Handler();
		hand.postDelayed(new Runnable()
		{
			@Override
			public void run()
			{
				change();
			}
			private void change()
			{
				if (flag)
				{
					trans.startTransition(8000);
					flag = false;
				} else
				{
					trans.reverseTransition(8000);
					flag = true;
				}
				handlechange1();
			}
		}, 8000);

	}

Upvotes: 2

happydude
happydude

Reputation: 3889

There is not really a built-in way to do this. TransitionDrawable is not designed with an infinite looping animation function. The easiest recommendation would be to use an Animation (alpha, scale, translate, etc.) on a View containing just one of your Drawables if you can.

A fairly easy hack would be to add a Handler and callback to your custom View holding your TransitionDrawable. When the View is created, the Handler can be set to your transition interval. The View would also implement Handler.Callback and inside its handleMessage(Message) method, it would call reverseTransition(int) on your TransitionDrawable.

A rough example is below:

public class myView extends View implements Handler.Callback {

    private Handler mHandler = new Handler(this);

    private int mDelay = 1000; // Delay in milliseconds.

    private Runnable mEvent = new Runnable() {
        public void run() {
            mHandler.removeCallbacks(mEvent);
            mHandler.postDelayed(mEvent, mDelay);
            Message message = mHandler.obtainMessage();
            mHandler.sendMessage(message);
        }
    };

    public View(Context context) {
        super(context);
        // Set your background TransitionDrawable.
        setBackgroundDrawable(...);
    }

    public handleMessage(Message message) {
        TransitionDrawable drawable = (TransitionDrawable) getBackgroundDrawable();
        drawable.reverseTransition(mDelay);
    }

    public void start() {
        mHandler.post(mEvent);
    }

    public void stop() {
        mHandler.removeCallbacks(mEvent);
    }

}

Call start() to start your continuous transition, stop() to stop it. It is a bit like creating your own animation, but it works in a pinch.

Upvotes: 1

Related Questions