Recently, I have been playing with Android development. Having already done some very basic Java development a long time ago, I was surprised how fast I came with my very first application.
Development tools are still lagging behind iOS & Windows Phone (espcially when it comes to the emulator, which is slow and outdated) but the documentation is very well written and complete. Moreover, the web is full of posts with questions (and their answers) so you usually do not get stuck without an answer for too long. When writing my Windows Phone application, I struggled a little to find some answers because of the lack of information. This wasn’t the case at all with Android development and that’s a good thing!
I have decided to describe my experience by providing a few hints I have discovered.
The first thing I’ll cover is transition animations between activities.
Activities
In Android development, an activity is basically a screen which the user can interact with. An application has a main activity which is first presented to the user. Doing specific actions, like taping on a menu, can then bring a new activity that is pushed over the previous activity. This creates a kind of stack. A tap on the back button usually goes back to the previous activity. When going from an activity to another one, Android animates the screen with a transition animation so that the switch appears smoother. By default, an explode animation is used and as we are going to see this transition can easily be customized.
When do transitions happen?
Transitions can happen in different places:
- When starting a new activity (likely started with an intent)
- When closing an activity (likely finished automatically or by pressing back button)
After starting or closing an activity, Android will automatically play default transitions. Fortunately, Android provides a method to override these transitions: overridePendingTransition().
The overridePendingTransition method
public void overridePendingTransition (int enterAnim, int exitAnim)
An enterAnim and exitAnim resources should be passed as parameters. The first one being the animation of the activity that will be started and the second one the animation of the current activity that will be finished.
Android animation resources are simple XML files in which attributes are transformations that will be applied to your activities. Example of transformations: alpha, scale, rotate, translate,… If you’ve done some CSS transformations as I do, this could be compared to the -webkit-transform CSS attribute.
Here is an example:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:toxdelta="0" android:duration="200" android:fromxdelta="100%"></translate>
</set>
In this example, a transition will be applied, moving from the right (fromXDelta=”100%”) to the right (toXDelta=”0”). For a single transition, two resources (at most) should be used. The documentation states that you can simply pass 0 for the transition, but I’m not sure what happens in that case (default transition? no transition at all?).
For our slide, we will use 4 transitions. The first two will be used when going from activity 1 to activity 2: the new activity must be moved to the left, the current activity onto the left, completely out of the screen, as shown below:
Here are the resulting animations:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:toxdelta="0" android:duration="200" android:fromxdelta="100%"></translate>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:toxdelta="-100%" android:duration="200" android:fromxdelta="0"></translate>
</set>
The last ones will be used when going back from activity 2 to activity 1:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:toxdelta="0" android:duration="200" android:fromxdelta="-100%"></translate>
</set>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:toxdelta="100%" android:duration="200" android:fromxdelta="0"></translate>
</set>
When to call overridePendingTransition?
According to the official Android documentation, the overridePendingTransition method should be called right after the start or finish of an activity. Starting from Android JellyBean (4.1+), it can also be specified through ActivityOptions but we won’t describe that method, preferring a more compatible one.
So we need to call it once we start our activity with the first two animations activity_in.xml and activity_out.xml that we have added into res/anim/ folder:
public void onShouldStartActivity() {
// creation of intent to start activity2
Intent intent = new Intent(this, Activity2.class);
startActivity(intent);
// Following the documentation, right after starting the activity
// we override the transition
overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
}
And we also need to call it once the user presses the back link into the actionBar menu (in case you have enabled it):
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id) {
// ...
// up button
case android.R.id.home:
finish();
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
return true;
}
return super.onOptionsItemSelected(item);
}
If we stop here, the transition will be used when going back from this activity using the action bar. However, if you press the back button, the default transition will be played, and that’s not what we want.
By default, when pressing the back button, the current activity will automatically be finished using default transition. What we need to do is to override the method onBackPressed:
@Override
public void onBackPressed() {
// finish() is called in super: we only override this method to be able to override the transition
super.onBackPressed();
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
}
This way we have the same transition being applied when using both methods of going back to previous activity. We could of course factorize the call to overridePendingTransition since it’s the same one.
Edit: I now have published on GitHub the full source code of the app I was developping when creating this article.