Ways to improve UI performance for Native Android

31 / Jan / 2024 by Aman Shandilya 0 comments

It is understood that using basic layout structures is an efficient way to create UI. Here, we need to understand that each widget that we add to our layout structure requires initialization and drawing. Below, we will discuss some of the Android API’s to improve UI performance.

ViewStub

ViewStub is a zero-sized view that is invisible initially. This can be used to lazily inflate the views at runtime. When the ViewStub is made visible, or we invoke the inflate() method, then it will be inflated. It is used to increase the performance of the UI as the view is only inflated at runtime if required else the view will not be added to the view hierarchy.

Giving a simple example to implement it while creating UI:

Declare the ViewStub in xml:

   <ViewStub
         android:id="@+id/viewstub"
         android:inflatedId="@+id/error_layout"
         android:layout="@layout/errorLayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
   />

After inflating the layout “errorLayout” ViewStub will be removed.

The preferred way to performe the inflation is :
ViewStub stub = findViewById(R.id.viewstub);
View inflated = stub.inflate();

When inflate() is invoked, the ViewStub is replaced by the inflated View and the inflated View is returned.

You can also get callback once the layout is inflated by using ViewStub.onInflateListener.

<merge> tag:

Excessive layout initialization and drawing can slows down the UI performance. We can inprove the performance by
flattening the layout.

The <merge> tag helps eliminate redundant view groups in your view hierarchy when including one layout within another.

Example: If we are using <include> tag to include another layout form another file without using merge.

layout1.xml:

<FrameLayout>
         <include layout="@layout/layout2"/>
</FrameLayout>

layout2.xml:

<FrameLayout>
         <TextView />
         <TextView />
</FrameLayout>
which is functionally equivalent to this single layout:
<FrameLayout>
         <FrameLayout>

              <TextView />
              <TextView />         

         </FrameLayout>
</FrameLayout>

and if we use <merge> tag with <include> tag then it will look like this:

layout2.xml:
<merge>
         <TextView />
         <TextView />
</merge>
This is functionally equivalent to this layout:
<FrameLayout>
         <TextView />
         <TextView />
</FrameLayout>

Note: If you just want to see how it will look like in android studio design editor then use tools namespace for
merge layout.

tools:parentTag="android.widget.LinearLayout"
tools:orientation="horizontal"

AsyncLayoutInflator:

It helps inflate layouts asynchronously. This can be used when part of the UI created lazily or in response to user interactions.

This allows the UI thread to remain responsive and animated while the relatively heavy inflation is being performed.

RecyclerView pool:

RecyclerView is the widget that we use frequently. The use of recyclerview inside a recyclerview is a very common design pattern nowadays.

As we already use the ViewHolder pattern while creating recyclerview, the same pool kind of concept can be used here when we are using nested recyclerview.

Because most of the time, we have the same ViewType between the different recycler reviews. As each recyclerview already has this pool concept individually but that can be used as common approach for all the recyclerview.

That means all the recyclerview can share same view pool.

This can be done using static RecycledViewPool class which remains in RecyclerView class.

RecyclerView.setRecycledViewPool(mRecycledViewPool)

Conclusion

Android provides multiple tools and libraries to continually improve the performance of your app in production, where it matters the most.

By implementing different approaches to improve UI performance, we can ensure for better app responsiveness and less ANR’s in Android applications.

Thanks for reading.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *