简体   繁体   English

绑定不适用于与 ViewStub 关联的片段

[英]Binding is not applying to a fragments associated with ViewStub

I have the current problem.我有当前的问题。 Right now I'm trying to lazy inflate bunch of fragments for better performance, which are part of a ViewPager.现在我正在尝试延迟膨胀一堆片段以获得更好的性能,这些片段是 ViewPager 的一部分。 The only solution I found was the usage of ViewStub.我找到的唯一解决方案是使用 ViewStub。 Here's where what I did so far:这是我到目前为止所做的:

abstract class ViewStubFragment: BaseFragment() {

    private lateinit var binding: FragmentViewStubBinding

    private var mSavedInstanceState: Bundle? = null
    private var hasInflated = false
    private var viewStub: ViewStub? = null
    private var visible = false

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentViewStubBinding.inflate(inflater, container, false)

        viewStub = binding.fragmentViewStub.viewStub
        viewStub?.layoutResource = getViewStubLayoutResource()
        mSavedInstanceState = savedInstanceState

        if(visible && !hasInflated) {
            val inflatedView = viewStub?.inflate()
            if (inflatedView != null) {
                onCreateViewAfterViewStubInflated(inflatedView, mSavedInstanceState)
            }
        }

        return binding.root
    }

    protected abstract fun onCreateViewAfterViewStubInflated(
        inflatedView: View,
        savedInstanceState: Bundle?
    )

    @LayoutRes
    protected abstract fun getViewStubLayoutResource(): Int


    @CallSuper
    protected fun afterViewStubInflated(originalViewContainerWithViewStub: View?) {
        hasInflated = true
        if (originalViewContainerWithViewStub != null) {
            val progressBar = binding.progressBar
            progressBar.visibility = View.GONE
        }
    }

    override fun onResume() {
        super.onResume()

        visible = true
        if (viewStub != null && !hasInflated) {
            val inflatedView = viewStub!!.inflate()
            onCreateViewAfterViewStubInflated(inflatedView, mSavedInstanceState)
            afterViewStubInflated(view)
        }
    }

The corresponding layout:对应的布局:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ProgressBar
            android:id="@+id/progress_bar"
            android:foregroundGravity="center"
            android:layout_gravity="center"
            android:indeterminate="true"
            android:layout_width="48dp"
            android:layout_height="48dp"/>
        <ViewStub
            android:id="@+id/fragment_view_stub"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>

</layout>

Part of the code from HomeFragment which I'm trying to lazily inflate:我试图懒惰地膨胀的 HomeFragment 的部分代码:

class HomeFragment : ViewStubFragment() {

    lateinit var binding: FragmentHomeBinding

........

    override fun onCreateViewAfterViewStubInflated(
        inflatedView: View,
        savedInstanceState: Bundle?
    ) {
        setDataBinding()
        observeLiveData()
    }

    override fun getViewStubLayoutResource(): Int {
        binding = FragmentHomeBinding.inflate(layoutInflater)
        return binding.root.sourceLayoutResId
    }

The problem is when setDataBinding() is called, the binding for some reason is not applied, thus Views like RecyclerView are not showing on the screen or click events aren not working.问题是调用setDataBinding()时,由于某种原因未应用绑定,因此 RecyclerView 之类的视图未显示在屏幕上或单击事件不起作用。 I have searched for hours but couldn't find solution related to this issue.我已经搜索了几个小时,但找不到与此问题相关的解决方案。

After another hour of struggle I found a solution, not sure if it is the best possible.经过一个小时的挣扎,我找到了一个解决方案,不确定它是否是最好的。

        if(visible && !hasInflated) {
            inflatedViewBinding = binding.fragmentViewStub.binding
            val inflatedView = viewStub?.inflate()
            if (inflatedView != null) {
                onCreateViewAfterViewStubInflated(inflatedView, mSavedInstanceState, inflatedViewBinding)
            }
        }

I passed the stored in ViewStubProxy binding (associated with the inflated layout) as argument in onCreateViewAfterViewStubInflated() and then assign the HomeFragment binding to it.我在onCreateViewAfterViewStubInflated()中将存储的ViewStubProxy绑定(与膨胀布局关联)作为参数传递,然后将 HomeFragment 绑定分配给它。

    override fun onCreateViewAfterViewStubInflated(
        inflatedView: View,
        savedInstanceState: Bundle?,
        binding: ViewDataBinding?
    ) {
        this.binding = binding as FragmentHomeBinding
        .......
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM