Most modern mobile apps carry out asynchronous operations, operations that would require the user to wait while the app is busy. Creating nice interactive loaders that match the purpose of your app will greatly improve the user experience in your app. For example the gif above showcases an example where i used an animation of a washing machine as a loading animation in a laundromat Android application. The process of creating animations on android application as been greatly simplified by the guys at Lottie: https://lottiefiles.com/. In this little article, i would outline the steps required to utilize these animations to make awesome loaders for Android.
1. First of all, we would need to search for an appropriate animation on https://lottiefiles.com/, there are many free or paid animations available on the site. They also have an amazing blog post detailing some neat loading animations at: https://lottiefiles.com/blog/inspiration/a-loading-spinner-slows-down-time-here-s-what-you-can-use-instead. Once you have selected an appropriate animation, you would have to create an account on the site, edit some of the colors if you would like using the animation editor and then download the animation in json format, and now we can move to the next step.
2. We have to add Lottie to our android project by adding
implementation'com.airbnb.android:lottie:$lottieVersion'
to your app level build.gradle, the latest version is 3.4.0 at the time of this publication, you can always check out the latest version at : https://github.com/airbnb/lottie-android.
3. Next, we have to move the downloaded json file to the res/raw/ resource directory as shown below:
Next we create an XML layout file to hold the LottieAnimationView, I like to use a FrameLayout so i can centralize the AnimationView. You can set a variety of attributes for the LottieAnimationView, like so:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.airbnb.lottie.LottieAnimationView
android:layout_width="150dp"
android:layout_height="150dp"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_repeatMode="reverse"
app:lottie_rawRes="@raw/dumbell_anim"
android:layout_gravity="center"
/>
</FrameLayout>
4. Next we have to create a DialogFragment that will handle showing, the loader. I created a LoadingDialogFragment.kt file, which is relatively simple file that displays the animation on a transparent background. Here is it:
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import androidx.fragment.app.FragmentManager
import com.initsng.fitnesscentral.R
class LoadingDialogFragment : DialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
isCancelable = false
return inflater.inflate(R.layout.loading_fragment, container, false)
}
//over rid this due to some issues that occur when trying to show a the dialog after onSaveInstanceState
override fun show(manager: FragmentManager, tag: String?) {
try {
val ft = manager.beginTransaction()
ft.add(this, tag)
ft.commitAllowingStateLoss()
} catch (ignored: IllegalStateException) {
}
}
}
We can initialize initialize, show or hide the loader using the methods shown below:
//Initialize Loader
private val loadingDialogFragment by lazy { LoadingDialogFragment() }
//Show Loader
if (!loadingDialogFragment.isAdded){
loadingDialogFragment.show(supportFragmentManager, "loader")
}
//Hide Loader
if (loadingDialogFragment.isAdded) {
loadingDialogFragment.dismissAllowingStateLoss()
}
Using MVVM and Livedata, I usually set my loading states from the viewmodel and observe the livedata object in the activity so i am able to use it as shown below:
viewModel.loading.observe(this, Observer{ loadingState ->
when(loadingState){
true -> showLoader()
false -> hideLoader()
}
})
Another example of using the Lottie animations as loaders is shown below:
I hope this article as been simple and straight forward enough for you to improve your loading UX on your Android applications. Credit goes to Chris Shaw https://lottiefiles.com/user/89764 for the washing machine animation, fortunately i could not find the original creator of the dumbbell animation :( Would love to hear any feedback or issues you encounter when using this or any way i can improve this article. Thank you reading!