美文网首页
include 替换成 ViewStub .

include 替换成 ViewStub .

作者: 王家匀匀 | 来源:发表于2021-01-27 17:21 被阅读0次

    ViewStub 的优点就是不用的布局,可以不加载。不像include,虽然没有显示,但是总要先加载布局。

    xml 需要修改:
    step1:
    <include>替换成<ViewStub>标签。

    step2:
    layout 属性换成 android:layout.
    注意,如果不修改,运行会奔溃。 报没有设置layout。

    step3:
    id 修改为带viewStub 的名字。不修改不报错,但是表意不清晰;

    step4:
    设置 android:inflatedId="@+id/your_layout"。
    注意:如果与约束性布局结合使用, android:inflatedId 属性值必须与 android:id一致。
    设置与 id不同的值不会报错,但是会导致约束失效。具体参考:
    https://stackoverflow.com/questions/47164398/how-to-use-viewstub-in-constraintlayout

    当与databinding 结合使用时,根据id获取viewStub.inflate获取到view,
    根据 DataBindingUtil.getBinding(view)获取到 viewStub 的binding。
    代码如下(这里的binding 是根布局binding):

         val inflateView = binding.contentViewStub.viewStub?.inflate()
         val newBinding = DataBindingUtil.getBinding<IncludeNewLayoutBinding>(inflateView)
         newBinding?.vm = vm 
    

    注意事项:ViewStub 只能inflate一次。在可能被复用的地方格外要注意(比如recyclerView 的adapter中)
    ViewStub inflate 后,就会被替换为对应的layout, 再获取父布局就为null.
    也就是 上面的代码,如果inflate后 ,binding.contentViewStub.viewStub 获取到的就是null。
    那么inflate后,怎么隐藏呢,设置 visibility 来控制。
    参考代码:

      if (binding.contentViewStub.isInflated) {
                    //viewStub 只能inflate 一次
                   binding.contentViewStub.binding?.root?.visibility = View.VISIBLE
      } else {
                    //这里viewStub肯定不为null
                    val inflateView = binding.contentViewStub.viewStub!!.inflate()
                    val newBinding = DataBindingUtil.getBinding<IncludeContentLayoutBinding>(inflateView)
                    newBinding?.vm = vm
       }
    
    



    题外话:
    来看下源码ViewStubProxy.isInflated() 怎么判断的:很显然,加载后返回true,没加载返回false。

        /**
         * Returns <code>true</code> if the ViewStub has replaced itself with the inflated layout
         * or <code>false</code> if not.
         *
         * @return <code>true</code> if the ViewStub has replaced itself with the inflated layout
         * or <code>false</code> if not
         */
        public boolean isInflated() {
            return mRoot != null;
        }
    

    getViewStub 可以看到,只要加载过就返回null.没有加载过就返回layout。
    那么用之前判断下有没有加载过。加载过,控制可见性;没加载,如果需要显示直接加载。

        /**
         * Returns the ViewStub in the layout or <code>null</code> if the ViewStub has been inflated.
         *
         * @return the ViewStub in the layout or <code>null</code> if the ViewStub has been inflated.
         */
        @Nullable
        public ViewStub getViewStub() {
            return mViewStub;
        }
    

    相关文章

      网友评论

          本文标题:include 替换成 ViewStub .

          本文链接:https://www.haomeiwen.com/subject/sbpazktx.html