Create a full page loading screen in Android
February 23, 2021
A typical loading screen best practices:
- Prevent any further user interaction
- Easily customisable
- Easy show/hide logic
Let’s see how to create one in Android
Creating a Loading screen
Our loading screen in this example is going to be pretty straightforward. Full height and width container with a logo/image in between.
Tip: You can put a background color of black/white with 10% visibility to make rest of your app UI translucent and give the user an idea that UI is blocked for any further interaction.
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading"
android:background="#31000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/loading_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/loading_image" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
This is how our loading screen should look like:

But how to use this layout?
Using FrameLayout we can ensure that our loading screen UI comes on top of your app UI.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Your rest of the App UI -->
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The Loading UI we defined above-->
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
How to block further user interaction?
Add a dummy touch listener to the loading layout.
loading_view.setOnTouchListener((view, motionEvent) -> true);
Making it easily customisable
DRY- Don’t repeat yourself.
We don’t need to put our loading screen xml in every layout. Let’s abstract it and use the
Define a separate xml file called loading.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/loading_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/digipay_logo" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
And include it in your activity/fragment like:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Your rest of the App UI -->
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/loading"
layout="@layout/loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
</FrameLayout>
Abstracting the show/hide logic
At this point, we can use the loading screen by simply setting loadingView.setVisibility(false|true) and our loading screen would work perfectly.
But wouldn’t it be nice if we had a simple API to handle visibility of our loading screen from anywhere inside our activity/fragment?
We’ll define a BaseActivity.java class, which inherits from the AppCompatActivity.java and extend/use that class in all of our activities. Similarly if we were working with fragments, we could create a BaseFragment class by extending the Fragment class.
public class MainActivity extends BaseActivity{
ConstraintLayout loading_view;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loading_view = (ConstraintLayout) findViewById(R.id.loading);
super.setView(loading_view);
}
}
Here we’re calling a setView() method of our super class(BaseActivity.java), to let it recognise the view which is associated with the loading container.
And in our BaseActivity.java:
public class BaseActivity extends AppCompatActivity {
ConstraintLayout loading_view = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected void setView(ConstraintLayout loading_view) {
this.loading_view = loading_view;
//To prevent user interaction
loading_view.setOnTouchListener((view, motionEvent) -> true);
}
public void showLoading(boolean toShow) {
if(loading_view!=null)
loading_view.setVisibility(toShow ? View.VISIBLE : View.GONE);
}
}
Now you can use the API showLoading(boolean) anywhere in your activity which extends our BaseActivity class and has been initiated with the loading screen view. Note that we can also abstract the code for setting the dummy onTouchListener in the BaseActivity class.