Android 带有FirestoreRecyclerAdapter和LifecycleOwner的嵌套RecyclerView不';t填充

Android 带有FirestoreRecyclerAdapter和LifecycleOwner的嵌套RecyclerView不';t填充,android,android-recyclerview,firebaseui,google-cloud-firestore,android-architecture-components,Android,Android Recyclerview,Firebaseui,Google Cloud Firestore,Android Architecture Components,我正在尝试创建一个嵌套的RecyclerView,其中水平的RecyclerView将显示为垂直的RecyclerView项。(UI看起来类似于Google Play商店) 因为我的数据集在FirebaseFirestore中,所以我使用FirestoreRecyclerAdapter来实现这一点 我的片段代码(此处存在父循环视图): 仪表板支架代码段: override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Dash

我正在尝试创建一个嵌套的RecyclerView,其中水平的RecyclerView将显示为垂直的RecyclerView项。(UI看起来类似于Google Play商店)

因为我的数据集在FirebaseFirestore中,所以我使用FirestoreRecyclerAdapter来实现这一点

我的片段代码(此处存在父循环视图):

仪表板支架代码段:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashboardHolder {
    val item = LayoutInflater.from(parent.context)
            .inflate(layout, parent, false)
    return DashboardHolder(item)
}
internal class DashboardHolder(item: View) : RecyclerView.ViewHolder(item) {

private val rowTitle: TextView = item.rowTitle
private val rowRecycler: RecyclerView = item.rowRecycler

fun bind(category: Category, owner: LifecycleOwner) {
    rowTitle.text = category.name
    rowRecycler.setHasFixedSize(true)
    val query = <some query>
    val adapter = DashboardProductsAdapter(
            FirestoreRecyclerOptions.Builder<Product>()
                    .productOption(query, owner),
            R.layout.item_dashboard_product)
    rowRecycler.adapter = adapter
}
}

可能的问题是什么?我应该在bind()方法之外创建子适配器吗?我应该跳过
stopListening()
回调,但这可能会导致内存泄漏。

我认为这里可能会出现一些问题。一旦我们弄明白了,我会更新这个答案

首先,我想确定您正在
onBindViewHolder()
中调用
bind()
,对吗

接下来,我很确定这不重要,但是您可以将init代码移动到
onViewCreated()
这样:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
        inflater.inflate(R.layout.layout_recyclerview, container, false)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val query = <some reference>
    val recycler = view.recyclerView
    recycler.setHasFixedSize(true)
    adapter = DashboardAdapter(this,
            FirestoreRecyclerOptions.Builder<Category>().categoryOption(query, this),
            R.layout.item_dashboard_row)
    recycler.adapter = adapter
}
private var currentAdapter: FirestoreRecyclerAdapter<...>? = null

fun bind(...) {
    currentAdapter?.let {
        it.stopListening() // Stop listening to database
        lifecycle.removeObserver(it) // Prevent automatic readdition of listeners
    }

    // Init adapter
    currentAdapter = ...
}
如果上述任何一项都不起作用,那么您将需要进行一些硬核调试,一点一点地逐步检查代码,直到您看到问题的症结所在。我建议添加以下断点:

  • 适配器的
    startListening()
    方法,确保调用了
    addChangeEventListener()
  • 适配器的
    onChildChanged()
    方法,请确保使用正确的值调用它
  • 遍历堆栈以查看内存,并确保所持有的引用是当前对象,而不是
    onStop()中的重影。
  • 所有的东西都在正确的地方?可能不是FirebaseUI或架构组件问题。顺便说一句,确保您使用的是最新的FUI版本
    3.1.0
    和AAC版本
    rc1

  • 我认为这里有几件事情可能会出错。一旦我们弄明白了,我会更新这个答案

    首先,我想确定您正在
    onBindViewHolder()
    中调用
    bind()
    ,对吗

    接下来,我很确定这不重要,但是您可以将init代码移动到
    onViewCreated()
    这样:

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
            inflater.inflate(R.layout.layout_recyclerview, container, false)
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val query = <some reference>
        val recycler = view.recyclerView
        recycler.setHasFixedSize(true)
        adapter = DashboardAdapter(this,
                FirestoreRecyclerOptions.Builder<Category>().categoryOption(query, this),
                R.layout.item_dashboard_row)
        recycler.adapter = adapter
    }
    
    private var currentAdapter: FirestoreRecyclerAdapter<...>? = null
    
    fun bind(...) {
        currentAdapter?.let {
            it.stopListening() // Stop listening to database
            lifecycle.removeObserver(it) // Prevent automatic readdition of listeners
        }
    
        // Init adapter
        currentAdapter = ...
    }
    
    如果上述任何一项都不起作用,那么您将需要进行一些硬核调试,一点一点地逐步检查代码,直到您看到问题的症结所在。我建议添加以下断点:

  • 适配器的
    startListening()
    方法,确保调用了
    addChangeEventListener()
  • 适配器的
    onChildChanged()
    方法,请确保使用正确的值调用它
  • 遍历堆栈以查看内存,并确保所持有的引用是当前对象,而不是
    onStop()中的重影。
  • 所有的东西都在正确的地方?可能不是FirebaseUI或架构组件问题。顺便说一句,确保您使用的是最新的FUI版本
    3.1.0
    和AAC版本
    rc1

  • 以下最新FUI异常:java.lang.RuntimeException:java.lang.NoSuchMethodException:[class com.firebase.ui.firestore.FirestoreRecyclerAdapter]位于android.arch.lifecycle.j.a(Lifecycling.java:111)的android.arch.lifecycle.j.a(Lifecycling.java:57)在android.arch.lifecycle.h$a.(LifecycleRegistry.java:346)在android.arch.lifecycle.h.a(LifecycleRegistry.java:162)在com.firebase.ui.firestore.FirestoreRecyclerAdapter.(FirestoreRecyclerAdapter.java:37)嗯,这似乎是一个完全不同的问题。确保您正在使用support lib 26.1.x,并尝试运行
    /gradlew clean
    。不确定会发生什么。是的,支持库是26.1.0,并且已经尝试过清理项目。我的应用程序只运行带有FUI 3.0.0的arch组件1.0.0-beta1。每当我尝试更新其中任何一个时,它都会崩溃。嗯,你能用DeobfUsicated堆栈跟踪创建一个GitHub问题吗?只有启用proguard的apk才会发生这种情况。请参阅此问题的最后评论。以下最新FUI异常:java.lang.RuntimeException:java.lang.NoSuchMethodException:[class com.firebase.ui.firestore.FirestoreRecyclerAdapter]位于android.arch.lifecycle.j.a(Lifecycling.java:111)的android.arch.lifecycle.j.a(Lifecycling.java:57)在android.arch.lifecycle.h$a.(LifecycleRegistry.java:346)在android.arch.lifecycle.h.a(LifecycleRegistry.java:162)在com.firebase.ui.firestore.FirestoreRecyclerAdapter.(FirestoreRecyclerAdapter.java:37)嗯,这似乎是一个完全不同的问题。确保您正在使用support lib 26.1.x,并尝试运行
    /gradlew clean
    。不确定会发生什么。是的,支持库是26.1.0,并且已经尝试过清理项目。我的应用程序只运行带有FUI 3.0.0的arch组件1.0.0-beta1。每当我尝试更新其中任何一个时,它都会崩溃。嗯,你能用DeobfUsicated堆栈跟踪创建一个GitHub问题吗?只有启用proguard的apk才会发生这种情况。请参阅此问题的最后评论。您好@Chandra Sekhar,我在Firestore RecyclerView中也面临同样的问题,在我的例子中,我调用父RecyclerView的onBindViewHolder中嵌套的RecyclerView的adapter.startListening(),而从不调用adapter.stopListening()。应用程序可以正常工作一段时间,但开始挂起并最终崩溃,我认为这可能是因为适配器.startListening()被多次调用而没有停止,从而导致内存泄漏。你找到解决这个问题的办法了吗。任何帮助都将不胜感激。您好@Chandra Sekhar,我在Firestore RecyclerView中也面临同样的问题,在我的例子中,我调用父RecyclerView的onBindViewHolder中嵌套的RecyclerView的adapter.startListening(),而从不调用adapter.stopListening()。我认为,该应用程序可以正常工作一段时间,但开始挂起并最终崩溃