0

我想要一个嵌套的RecyclerView其中一个水平的RecyclerView将显示为垂直RecyclerView的项目。 (UI与Google Play Store类似)与FirestoreRecyclerAdapter和LifecycleOwner嵌套RecyclerView不会填充

由于我的数据集位于FirebaseFirestore中,因此我使用FirestoreRecyclerAdapter来实现此目的。

我的片段的代码(家长RecyclerView这里存在):

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { 
    val view = inflater.inflate(R.layout.layout_recyclerview, container, false) 
    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 
    return view 
} 

DashboardAdapter片段:

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

DashboardHolder片段:

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 
} 
} 

很明显,DashboardHolder(父视图架)里面有RecyclerView。绑定时,子适配器被创建并设置为子RecyclerView。

当我第一次加载碎片时,一切正常,加载正常。但是,当我点击主页按钮并再次回到应用程序,只有父RecyclerView被填充,而不是孩子。

我开始挖掘更多后,发现这是因为LifecycleOwner我正在创建FirestoreRecyclerOptions。如果我没有设置并手动拨打startListening()stopListening(),那么行为也是一样的。但如果我不打电话stopListening(),它工作正常。

更新片段的代码:

override fun onStart() { 
    super.onStart() 
    adapter.startListening() 
} 

override fun onStop() { 
    super.onStop() 
    // If I comment this out, everything works fine 
    // But putting this in code doesn't populate the child RecyclerView 2nd time 
    adapter.stopListening() 
} 

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

回答

0

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

首先,我想确保你打电话bind()onBindViewHolder(),对不对?

接下来,我敢肯定,这并不重要,但你能不能将你的初始化代码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 
} 

至于你的观点持有者,有一个核心的问题,您需要解决这个问题有点棘手。 bind()将在onStart()onStop之间被多次调用,这意味着您将剩下大量的挂接适配器,因为当适配器被反弹时stopListening()不会被调用。为了解决这个问题,你需要保存在你的财产适配器和每次清除它在bind()像这样:

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 = ... 
} 

如果以上都没有效果的,你需要通过做一些铁杆调试一点点地逐步浏览你的代码,直到你看到事情正在崩溃。这些都是断点我建议增加:

  1. 适配器的startListening()方法,确保addChangeEventListener()
  2. 适配器的​​方法,确保它被称为用正确的值
  3. 走栈,通过你的记忆看并确保您所持有的参考文献是当前对象而不是来自onStop()
  4. 所有内容正在正确的位置调用?可能不是FirebaseUI或架构组件问题。顺便说一下,请确保您使用的是最新的FUI版本3.1.0和AAC版本rc1
+0

下面最新FUI例外:了java.lang.RuntimeException:java.lang.NoSuchMethodException: [类com.firebase.ui.firestore.FirestoreRecyclerAdapter] 在android.arch.lifecycle.ja(Lifecycling.java: 111) at android.arch.lifecycle.ja(Lifecycling.java:57) at android.arch.lifecycle.h $ a。 (LifecycleRegistry.java:346) at android.arch.lifecycle.h.a(LifecycleRegistry.java:162) at com.firebase.ui.firestore.FirestoreRecyclerAdapter。 (FirestoreRecyclerAdapter.java:37) –

+0

嗯,这似乎是一个完全不同的问题。确保你使用的是支持lib 26.1.x并且运行'./gradlew clean'。不知道可能会发生什么。 – SUPERCILEX

+0

是支持库是26.1.0并且已经尝试了清理项目。我的应用程序只能运行带有FUI 3.0.0的拱形组件1.0.0-beta1。每当我尝试更新其中的任何一个时,它都会崩溃。 –