We consider our layout to be nice. It is pretty. But can it be more entertaining? Sure it can! If we make our layout more interactive we will achieve a better user experience and attract users to use it. We will achieve that by adding some animations. Animations can be defined through the code or by animating view properties. We will improve each of the screens by adding simple and effective opening animations.
Animations defined as resources are located in the anim resources directory. We will need a few animation resources there--fade_in, fade_out, bottom_to_top, top_to_bottom, hide_to_top, hide_to_bottom. Create them and define them according to these examples:
- fade_in:
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android=
"http://schemas.android.com/apk/res/android" android:duration="300" android:fromAlpha="0.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="1.0" />
- fade_out:
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android=
"http://schemas.android.com/apk/res/android" android:duration="300" android:fillAfter="true" android:fromAlpha="1.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.0" /> - bottom_to_top: <set xmlns:android=
"http://schemas.android.com/apk/res/android" android:fillAfter="true" android:fillEnabled="true" android:shareInterpolator="false"> <translate android:duration="900" android:fromXDelta="0%" android:fromYDelta="100%" android:toXDelta="0%" android:toYDelta="0%" /> </set>
- top_to_bottom:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" android:fillEnabled="true" android:shareInterpolator="false"> <translate android:duration="900" android:fromXDelta="0%" android:fromYDelta="-100%" android:toXDelta="0%" android:toYDelta="0%" /> </set>
- hide_to_top:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" android:fillEnabled="true" android:shareInterpolator="false"> <translate android:duration="900" android:fromXDelta="0%" android:fromYDelta="0%" android:toXDelta="0%" android:toYDelta="-100%" /> </set>
- hide_to_bottom:
<set xmlns:android=
"http://schemas.android.com/apk/res/android" android:fillAfter="true" android:fillEnabled="true" android:shareInterpolator="false"> <translate android:duration="900" android:fromXDelta="0%" android:fromYDelta="0%" android:toXDelta="0%" android:toYDelta="100%" /> </set>
Take a look at this example and the attributes you can define. In the fade animation example, we animated an alpha property for the view. We set the animation duration, from, and to alpha values and the interpolator we will use for the animation. In Android, for your animations you can choose one of these interpolators:
- accelerate_interpolator
- accelerate_decelerate_interpolator
- bounce_interpolator
- cycle_interpolator
- anticipate_interpolator
- anticipate_overshot_interpolator
- and many others, all defined in--@android:anim/...
For other animations we defined the translation with from and to parameters.
Before we use these animations we will adjust some backgrounds so there is no gap in our layouts before the animation starts. For activity_main, add the background for Toolbar parent view:
android:background="@android:color/darker_gray"
For activity_note and activity_todo nest toolbar in one more parent so the final color is the same as the color for the title field below the toolbar:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/black_transparent_40" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/black_transparent_40" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/colorPrimary" android:elevation="4dp" />
Finally we will apply our animations. We will use fade in and out animations for our screens, opening and closing. Open BaseActivity and modify it like this:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) overridePendingTransition(R.anim.fade_in, R.anim.fade_out) setContentView(getLayout()) setSupportActionBar(toolbar) Log.v(tag, "[ ON CREATE ]") }
We overrode transition effects by using the overridePendingTransition() method that takes enter and exit animations as parameters.
Update your onResume() and onPause() methods too:
override fun onResume() { super.onResume() Log.v(tag, "[ ON RESUME ]") val animation = getAnimation(R.anim.top_to_bottom) findViewById(R.id.toolbar).startAnimation(animation) } override fun onPause() { super.onPause() Log.v(tag, "[ ON PAUSE ]") val animation = getAnimation(R.anim.hide_to_top) findViewById(R.id.toolbar).startAnimation(animation) }
We created an instance of animation and applied it on the view using the startAnimation() method. getAnimation() method is ours. We defined it. So, add the implementation to BaseActivity:
protected fun getAnimation(animation: Int): Animation =
AnimationUtils.loadAnimation(this, animation)
Since we are using Kotlin, to make it available to all activities, not just the ones that are extending BaseActivity change method to be extension function like this:
fun Activity.getAnimation(animation: Int): Animation =
AnimationUtils.loadAnimation(this, animation)
Build your application again and run it. Open and close screens multiple times to see how our animations are working.