一、介绍
dataBinding在之前的文章中已介绍了。接下来我将介绍dataBinding在布局中使用include与viewStub的细节。
二、详解
公共layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="one" />
<Button
android:id="@+id/btn_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="two" />
<Button
android:id="@+id/btn_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="three" />
</LinearLayout>
</layout>
include:
include在layout的中,是将其他布局导入到当前布局,作为当前布局的内容。这种做法,可以简化布局文件,以及简化代码,将常用的布局作为公共布局资源,提供给其他布局使用。
但是在databinding中。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="IncludeViewStubBind"></data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sssssssssssssss"
/>
<include layout="@layout/view_include_viewstub" />
<ViewStub
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout="@layout/view_include_viewstub" />
</LinearLayout>
</layout>
有人会发现,在绑定完,调用id发现并没有找到include中的viewid
找不到的原因有两种
1.跟布局不是layout,如果需要支持databinding,你的公共布局根布局设置为layout。
答案:参考上面的公共布局
2.include的没有自己的id
<include layout="@layout/view_include_viewstub" />
答案:
<include
android:id="@+id/child"
layout="@layout/view_include_viewstub" />
引用:
如果你设置了include的id,但是导入的布局的根布局不是layout,同样也只能bind.child,获取不到child的子布局
这是ViewDataBinding与id生成的问题,如果有人有livedata的问题,可以参考:
Android DataBinding之布局include 和 viewStub详解与使用(六)_databinding viewstub_蜗牛、Z的博客-CSDN博客
即使在include的layout设置了<data class="name">也不影响,因为include的layout的parent是root,他的parentid其实就是include。
ViewStub:
ViewStub在复杂的大型view中使用的比较多,这个view控件的用处是即使你导入在view,不手动添加也不会被加载,翻译就是动态加载,这样可以降低内存和性能,在优化内存时,经常被用到。
ViewStub的layout和include有点区别,他的layout是一个独立的,也就是说,依赖parent view初始化,有自己的独立管理。
所以在ViewStub初始化时,我们必须要指定layout的data class 节点。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="MyViewStubBind"></data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="one" />
</LinearLayout>
</layout>
所以,这里的ViewDataBinding不在依赖整个页面的,而是有自己独立的。
绑定如下:
lateinit var stubView:MyViewStubBind
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bind = DataBindingUtil.setContentView(this, R.layout.layout_databind_include_viewstub)
if (!bind.stubinfo.isInflated) {
val viwe=bind.stubinfo.viewStub?.inflate()
stubView= DataBindingUtil.bind<MyViewStubBind>(viwe!!)!!
}
stubView.btnOne.setOnClickListener {
showToast("viewStb")
}
}
注意:
即使viewStub有自己的ViewDataBinding,但是整个页面也要先绑定,否则viewStub无法完成初始化,也会报错。
如果你的一个页面中使用了多个viewStub,那么整个页面ViewDataBinding count=1+viewStubSize
ViewStub的layout中view的操作,使用ViewStub的ViewDataBinding对象,页面root是无法将viewStub的layout view生成到自己的bind中。
三、总结:
以上只是databinding中ViewDataBinding如何操作include与viewStub,如果你的项目中使用了MVVM模式,引入了LiveData,不知道如何将数据通过LiveData传递给include与ViewStub,看下面的文字即可:
Android DataBinding之布局include 和 viewStub详解与使用(六)_databinding viewstub_蜗牛、Z的博客-CSDN博客