在Android数据绑定框架中,我知道你可以通过一个扩展的对象来实现 baseObservable
到布局xml,使用 @Bindable
在getters和do notifyPropertyChanged(BR.xxx)
来重新评估相关部分。
我不明白的是:如果不用上面的大部分东西,直接在xml中调用getter,什么时候会被评估?
下面是代码。
my_widget.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="someViewModel"
type="com.example.SomeViewModel" />
</data>
<androidx.cardview.widget.CardView>
<View
android:id="@+id/testView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="@{someViewModel.getName() ? View.VISIBLE : View.GONE}" />
</androidx.cardview.widget.CardView>
</layout>
MyView.java
MyWidgetBinding binding = MyWidgetBinding.inflate(LayoutInflater.from(mContext), parent, false);
binding.setSomeViewModel(someViewModel);
问题:
如果 someViewModel.name
变化,是否 testView
的可见性刷新?
什么时候 someViewModel.getName()
得到评估的频率还是多少?
如果表达式比较复杂,比如说。android:visibility="@{func(otherVariable, someViewModel.getName()) ? View.VISIBLE : View.GONE}"
,比如说 otherVariable
是另一个在上面数据部分定义的变量,如果以某种方式 otherVariable
得到重新设置,那么 someViewModel.getName()
将得到评估和 testView
将反映最新的可见度值,对吗?
继问题3之后,如果 otherVariable
改为 otherVariable.a
哪儿 a
是一个 "可绑定 "字段,并且 notifyPropertyChanged(BR.a)
所谓 otherVariable
然后 someViewModel.getName()
也将得到重新评估和 testView
将反映最新的可见性值,对吗?
此外,如果我重新设置 someViewModel
呼叫 binding.setSomeViewModel()
但通过在SAME someViewModel
例如,它有什么作用吗?表达式会不会被重新评估?
如果someViewModel.name发生变化,testView的可见性是否会刷新?
这取决于你使用的底层技术。是LiveData吗?是的 BaseObservable 你必须手动通知观察到的属性发生了变化。
SomeViewModel.getName()什么时候被评估或者多久评估一次?
LiveData ? 当你设置了一个值时。当你通知它的时候,BaseObservable
与第2点相同
如果你改变了底层的值,并正确地通知这个变化,它将得到相应的传播。如果你改变了观察对象的实例,它就不会被传播。
我建议你创建自定义的绑定适配器,用于可变的可见性,并使用LiveData来更新可见性。
代码 。
@BindingAdapter("mutableVisibility")
fun setMutableVisibility(view: View, visibility: MutableLiveData<Boolean>) {
val parentActivity: AppCompatActivity? = view.getParentActivity()
if (parentActivity != null) {
visibility.observe(
parentActivity,
Observer { value -> if (value) view.visibility = View.VISIBLE
else view.visibility = View.GONE})
}
}
为了获得父活动,创建ActivityExtensions.kt文件,并在其中添加以下功能。
fun View.getParentActivity(): AppCompatActivity?{
var context = this.context
while (context is ContextWrapper) {
if (context is AppCompatActivity) {
return context
}
context = context.baseContext
}
return null
}
并在ViewModel中。
//Other code here...
val itemVisibility = MutableLiveData<Boolean>()
//Other logic here to init itemVisible
if(itemVisibile) itemVisibility.value = true else itemVisibility.value = false
最后是layoutItem 。
<View
android:id="@+id/testView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:mutableVisibility ="@{viewModel.itemVisibility}" />