前言
在做性能优化的时候,发现很多布局使用的include标签直接导入,然后通过Databing直接控制显示隐藏。当想改写成ViewStub的时候,想按照普通View的写法创建一个BindingAdapte,会直接报错BR.xxx无法找到,不过系统还是提供了一个入口给我们,如下,所以我们可以直接重写一下
@RestrictTo(RestrictTo.Scope.LIBRARY)
@Untaggable({"android.view.ViewStub"})
@BindingMethods({
@BindingMethod(type = android.view.ViewStub.class, attribute = "android:layout", method = "setLayoutResource")
})
public class ViewStubBindingAdapter {
@BindingAdapter("android:onInflate")
public static void setOnInflateListener(ViewStubProxy viewStubProxy,
OnInflateListener listener) {
viewStubProxy.setOnInflateListener(listener);
}
}
实现
BindingAdapter实现
class ViewStubInflationProvoker(
listener: ViewStub.OnInflateListener = ViewStub.OnInflateListener { _, _ -> }
) : ViewStub.OnInflateListener by listener {
companion object {
@JvmStatic
fun provideIf(clause: Boolean): ViewStubInflationProvoker? {
return if (clause) {
ViewStubInflationProvoker()
} else {
null
}
}
}
}
object ViewStubBindAdapter {
@JvmStatic
@BindingAdapter("android:onInflate")
fun setOnInflateListener(
viewStubProxy: ViewStubProxy,
listener: ViewStub.OnInflateListener?
) {
if (viewStubProxy.isInflated) {
viewStubProxy.root.visibility = View.GONE.takeIf { listener == null } ?: View.VISIBLE
return
}
if (listener is ViewStubInflationProvoker) {
viewStubProxy.viewStub?.inflate()
}
}
}
xml中使用
<ViewStub
android:id="@+id/test_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout="@layout/test_sub_layout"
android:onInflate="@{ViewStubInflationProvoker.provideIf(model.visible)}"
app:model="@{model}"
tools:visibility="visible" />
当ViewStub初始化的时候,如果我们需要执行某些初始化操作,可以添加监听
binding.testStub.setOnInflateListener { stub, inflated ->
Toast.makeText(this, "加载完成", Toast.LENGTH_SHORT).show()
}
这样,当我们想改写include为ViewStub的时候,就可以直接替换而不用手动控制
参考链接:https://stackoverflow.com/questions/56779550/can-you-use-a-bindingadapter-on-a-viewstub