Using Android ViewStub to improves layout performance

Hello viewer, You can now have our Tutorial Lessons in your android mobile device and read it offline.
Download kotlin Programming APP on PlayStore
Download Website SEO Lessons APP on PlayStore

Using ViewStub on Android improves layout performance.

In Android development, Android ViewStub is the technology we have to contact to display. Often, as more and more complex View View, the overall layout of the performance will decline. Here introduced in some scenarios to enhance Layout performance View, it is ViewStub.

Using Android ViewStub to improves layout performance - Using Android ViewStub to improves layout performance - Using Android ViewStub to improves layout performance - android ViewStub

what is Android ViewStub?

  • ViewStub is a subclass of View
  • It is not visible and has a size of 0
  • Used to delay loading layout resources

Note, on the interpretation of Stub

A stub is a small program routine that substitutes for a longer program, capable to be loaded later or that is located distant

In Java, a stub is a code that is used instead of associated code or unimplemented code.

Android ViewStub to improves layout performance.

ViewStub uses the scene

As shown in FIG,

  • It contains a ListView such as Item etc.
  • Each Item also contains their corresponding sub-topics,
  • But the sub-topic View (blue area) only in the click button to expand really need to load.
  • If the default view of the sub-topics loaded, it will cause memory consumption and CPU consumption

Therefore, this time on the ViewStub on the use of the. ViewStub can be used to delay loading layout resources.

ViewStub how to use

1. Use the ViewStub tab in the layout file

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

     xmlns:android="http://schemas.android.com/apk/res/android"

     xmlns:tools="http://schemas.android.com/tools"

     android:layout_width="match_parent"

     android:layout_height="match_parent"

     android:paddingLeft="@dimen/activity_horizontal_margin"

     android:paddingRight="@dimen/activity_horizontal_margin"

     android:paddingTop="@dimen/activity_vertical_margin"

     android:paddingBottom="@dimen/activity_vertical_margin"

     tools:context="com.droidyue.viewstubsample.MainActivity">



     <Button

          android:id="@+id/clickMe"

          android:text="Hello World!"

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"/>



     <ViewStub

          android:id="@+id/myViewStub"

          android:inflatedId="@+id/myInflatedViewId"

          android:layout="@layout/include_merge"

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"

          android:layout_below="@id/clickMe"

     />

</RelativeLayout>
2. In the code, inflate the layout
ViewStub myViewStub = (ViewStub)findViewById(R.id.myViewStub);
if (myViewStub != null) {
     myViewStub.inflate();
 //myViewStub.setVisibility(View.VISIBLE);
}

-Using Android ViewStub to improves layout performance.

 

ViewStub on the matter

  • In addition to inflate method, we can also call setVisibility() method to load the layout file
  • Once the loading layout is complete, ViewStub is removed from the current layout level
  • android:id specified ViewStub ID, used to look ViewStub delayed loading
  • android:layout delay loading layout resource id
  • android:inflatedId layout rewritten id loaded here RelativeLayout of id

ViewStub deficiencies

The official document has such a description

Note: One drawback of ViewStub is that it does not currently support the tag in the layouts to be inflated.

Meaning ViewStub not support <merge> tag.

About the unsupported <merge> level tag, we performed a simple validation

-Using Android ViewStub to improves layout performance.

Verification 1: direct label

Below, we have the layout file named merge_layout.xml merge_layout.xml 

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="Yes"/>
<Button
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="No"/>
</merge>

Replace the corresponding ViewStub’s android: layout property values, after running (click the Button button) to get the following crash

  E AndroidRuntime: android.view.InflateException: Binary XML file line # 1: <merge /> can be used only with a valid ViewGroup root and attachToRoot = true
  E AndroidRuntime: at android.view.LayoutInflater.inflate (LayoutInflater.java:551)
  E AndroidRuntime: at android.view.LayoutInflater.inflate (LayoutInflater.java:429)
  E AndroidRuntime: at android.view.ViewStub.inflate (ViewStub.java:259)
  E AndroidRuntime: at com.droidyue.viewstubsample.MainActivity $ 1.onClick (MainActivity.java:20)
  E AndroidRuntime: at android.view.View.performClick (View.java:5697)
  E AndroidRuntime: at android.widget.TextView.performClick (TextView.java:10815)
  E AndroidRuntime: at android.view.View $ PerformClick.run (View.java:22526)
  E AndroidRuntime: at android.os.Handler.handleCallback (Handler.java:739)
  E AndroidRuntime: at android.os.Handler.dispatchMessage (Handler.java:95)
  E AndroidRuntime: at android.os.Looper.loop (Looper.java:158)
  E AndroidRuntime: at android.app.ActivityThread.main (ActivityThread.java:7237)
  E AndroidRuntime: at java.lang.reflect.Method.invoke (Native Method)
  E AndroidRuntime: at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1230)
  E AndroidRuntime: at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)
  E AndroidRuntime: Caused by: android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRoot = true
  E AndroidRuntime: at android.view.LayoutInflater.inflate (LayoutInflater.java:491)
  E AndroidRuntime: ... 13 more

Visible, direct <merge> tag, ViewStub is not supported.

-Using ViewStub on Android improves layout performance.

Verify two Indirect ViewStubs

The following layout indirect use merge tags. File named include_merge.xml include_merge.xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
    <include layout="@layout/merge_layout"/>
</LinearLayout>

Then modify ViewStub the android:layout value, run, everything is normal.

In addition, this case is also verified ViewStub of <include> tag supports good.

On the point of ViewStub code analysis

Inflate vs setVisibility

The common thing about both inflate and setVisibility is that you can implement a load layout

/**

 * When visibility is set to {@link #VISIBLE} or {@link #INVISIBLE},

 * {@link #inflate()} is invoked and this StubbedView is replaced in its parent

 * by the inflated layout resource.

 *

 * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.

 *

 * @see #inflate()

 */

 @Override

 public void setVisibility(int visibility) {

     if (mInflatedViewRef != null) {

         View view = mInflatedViewRef.get();

         if (view != null) {

              view.setVisibility(visibility);

         } else {

              throw new IllegalStateException("setVisibility called on un-referenced view");

         }

     } else {

         super.setVisibility(visibility);

         if (visibility == VISIBLE || visibility == INVISIBLE) {

               inflate();

         }

     }

}

setVisibility only when ViewStub first delay initialization, and visibility is non- GONE called when inflate method.

-Using ViewStub on Android improves layout performance.

Inflate source

By reading the following inflate method implementation, we will be more understanding

  • Android: inflatedId use
  • ViewStub is removed from the view hierarchy after initialization
  • ViewStub’s layoutParameters application
  • MInflatedViewRef Weak reference form, the establishment ViewStub and load the View link.
/**

 * Inflates the layout resource identified by {@link #getLayoutResource()}

 * and replaces this StubbedView in its parent by the inflated layout resource.

 *

 * @return The inflated layout resource.

 *

 */

 public View inflate() {

      final ViewParent viewParent = getParent();



      if (viewParent != null && viewParent instanceof ViewGroup) {

           if (mLayoutResource != 0) {

                final ViewGroup parent = (ViewGroup) viewParent;

                final LayoutInflater factory = LayoutInflater.from(mContext);

                final View view = factory.inflate(mLayoutResource, parent, false);



                if (mInflatedId != NO_ID) {

                     view.setId(mInflatedId);

                }



                final int index = parent.indexOfChild(this);

                parent.removeViewInLayout(this);



                final ViewGroup.LayoutParams layoutParams = getLayoutParams();

                if (layoutParams != null) {

                      parent.addView(view, index, layoutParams);

                } else {

                      parent.addView(view, index);

                }



                mInflatedViewRef = new WeakReference<View>(view);
                if (mInflateListener != null) {

                      mInflateListener.onInflate(this, view);
                }
                return view;
          } else {
                throw new IllegalArgumentException("ViewStub must have a valid layoutResource");

          }

     } else {
          throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");

     }
}

ViewStub on the study of these, we hope to optimize the view on the help and inspiration.

About The Author

Related posts

Leave a Reply