ViewStub使用BindingAdapter

/ 0评 / 26

前言

在做性能优化的时候,发现很多布局使用的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

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注