ViewStub的使用及原理

最近项目中有需求,需要添加功能引导,如果用户是第一次使用,那么就显示功能引导,之后则不再显示。感觉这样的需求正好可以利用ViewStub来实现,更节省资源。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    ..............
    
    <ViewStub 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lay_guide"
        android:layout="@layout/guide_main_tab"/>
    
</RelativeLayout>
if(!GuidePreference.isGuide(getApplicationContext(), GuidePreference.MAIN_TAB_V4)){
  ViewStub stub = (ViewStub) findViewById(R.id.lay_guide);
  if(stub==null){
    return ;
  }
  mFilpper = (ViewFlipper) stub.inflate() ;
  mFilpper.setOnClickListener(new View.OnClickListener() {
                
    @Override
    public void onClick(View v) {
      guideSwitch() ;
    }
  });
}

查看ViewStub的源码,inflate()部分如下:

public View inflate() {
        final ViewParent viewParent = getParent();

        if (viewParent != null && viewParent instanceof ViewGroup) {
            if (mLayoutResource != 0) {
                final ViewGroup parent = (ViewGroup) viewParent;
                final LayoutInflater factory;
                if (mInflater != null) {
                    factory = mInflater;
                } else {
                    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其实只相当于一个占位View而已,在未inflate之前,高宽都是0,只保存了在parent中的index和layoutParmas而已,在inflate时,用mLayoutResource来替换掉自己。这比自己平时动态往ViewGroup里面添加view的确要少一些操作,方便多了。

原文地址:https://www.cnblogs.com/alexthecoder/p/4191370.html