之前写过DataBinding在adapter中的简单使用,今天来说一下在Activity和Fragment中的使用区别
首先是Activity中的用法:
先确定好布局:
<data>
<variable
name="dataBean"
type="com.cx.retrofitdemo.bean.HouseDetail.Data" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/contentTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{dataBean.HouseInfo.title}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
注意<data>...<data>标签中的这一部分,是布局中databinding相关的核心部分,我自己的理解是这个不居中需要引用的数据模型是来自哪里的,就在这里定义。
TextView中就是这样引用: android:text="@{dataBean.HouseInfo.title}",这样布局部分的代码就完成了。
接下来是activity代码部分:使用DataBindingUtil.setContentView方法来取代 setContentView()
var dataBinding = DataBindingUtil.setContentView<ActivityDetailLayoutBinding>( this, R.layout.activity_detail_layout )
接口部分我是在viewmodle中请求的
class DetailViewModel constructor(retrofitAPI: RetrofitAPI) : BaseViewModel(retrofitAPI) {
val detailsLiveData by lazy { MutableLiveData<BaseBean<HouseDetail.Data>>() }
fun getNHDetails() {
val objectType: Type = object : TypeToken<BaseBean<HouseDetail.Data>>() {}.type
var baseBean = BaseBean(data = HouseDetail.Data())
viewModelScope.launch {
withContext(Dispatchers.IO) {
...
//这里调接口拿到返回值,使用liveData存放返回的数据
detailsLiveData.postValue(nhBean)
}
}
}
}
class DetailViewModelManagerFactory(private val retrofitAPI: RetrofitAPI) :
ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return DetailViewModel(retrofitAPI) as T
}
}
接着在activity中初始化ViewModel:
var detailViewModel = ViewModelProvider(
this,
DetailViewModelManagerFactory(retrofitAPI)
).get(DetailViewModel::class.java)
接口数据拿到后,在activity中调用detailViewModel.detailsLiveData.observe()方法来对 dataBinding.dataBean进行数据绑定:
detailViewModel.detailsLiveData.observe(this, Observer {
when (it.resultState) {
ResultState.LOADING -> {
contentTV.text = "正在加载数据"
}
ResultState.ERROR -> {
contentTV.text = "数据加载错误"
}
ResultState.SUCCESS -> {
contentView.contentDetail.text = "返回$it"
contentView.contentDetail.text = it.data.goodBuildings[0].name
dataBinding.dataBean = it.data
}
}
})
这样就完成了在activity中进行网络请求并使用Databinding来进行数据绑定的全部过程。
接下来是fragment,与Activity不同的地方是绑定布局的方法:用下面方式来取代inflater.inflate(R.layout.frag_sec_layout, null)
var binding = DataBindingUtil.inflate<FragSecLayoutBinding>(
inflater,
R.layout.frag_sec_layout,
null,
false
)
其他请求接口和数据绑定的方式都跟Activity一样,布局资源也是一样的写法。
稍微总结一下,使用DataBinding的流程:在布局文件定义好需要使用的数据模型,用<data>标签包裹起来,在控件中引用方式:@{}
在activity或fragment中设置布局资源都需要通过 DataBindingUtil来引用并得到LayoutBinding对象,具体引用方式可参照上面的代码,接下来就是按业务需求拿到数据之后,使用LayoutBinding对象来对数据进行绑定即可。
之前看了很多关于 DataBinding的使用文章,觉得又要在布局中写代码,又要在代码中绑定什么的好麻烦,中途放弃好几次。自己写这个demo之后才知道也没有想象中那么复杂,完成之后甚至会觉得比先前在代码中对控件一一赋值要简介明了很多。文章写得很烂,很可能会看不明白,建议各位亲们对照官方文档自己写一遍,一定会有所提升的。