当片段重新创建到前台时,Recyclerview 会重新创建
Recyclerview gets recreated when fragment is recreated coming to foreground
我有一个片段,其中有一个 RecyclerView
显示来自观察者的列表,该观察者观察来自 Room db 的列表数据的变化。它是这样工作的 - FragmentA
有列表 RecyclerView
并且当用户点击一个项目时,它会打开(替换)另一个 FragmentB
这是一个列表详细信息片段,用户可以在其中编辑列表详细信息项目并保存它(在数据库中更新),LiveData
将完成它的工作并更新列表。但是当我按下后退按钮时,FragmentA
的视图被重新创建并且另一个相同的观察者被订阅,如下面的代码所示 -
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupUI(view);
viewModel.getInspections().observe(this, inspectionsList -> {
setUpMainAdapter(inspectionsList); //setting Recyclerview adapter on recyclerview.
})
}
我找到了这个问题的解决方案in this article,它被写成使用getViewLifecycleOwner()
而不是this
,这样当片段视图层次结构改变时观察者也被取消订阅.
现在我的问题是,如果我从 FragmentB
返回到 FragmentA
,setUpMainAdapter()
会再次被调用,并且会在 recyclerview 上设置一个新的适配器。当我检查旧的适配器实例是否仍然存在时。如果我这样做 adapter.notifyItemChanged(position)
它不起作用并且 recyclerview 没有任何显示(因为视图已重新创建)。那么,在这里设置 recyclerview 的适配器是正确的方法吗?因为一次又一次地设置主适配器并且不能使用适配器的通知方法来更新一个项目感觉很奇怪。
use getViewLifecycleOwner()
instead of this so that the observers are also unsubscribed when the fragment view hierarchy is changed.
这是根本。当你在 RxJava 等其他框架中注册观察者时,你总是需要最终取消订阅它。使用 LiveData,生命周期所有者会为您做这件事。但是当你使用 this
作为生命周期所有者时,观察者只会在片段被销毁时被删除,但它们不会在视图被销毁时被删除!所以你最终会有多个观察者引用被破坏的视图,这会造成内存泄漏。
So, is setting up the adapter to the recyclerview is the right approach here?
我通常在 onViewCreated
中创建我的适配器,但我认为如果您确保在新的 RecyclerView 上再次设置它,您应该可以重新使用旧的适配器。
我有一个片段,其中有一个 RecyclerView
显示来自观察者的列表,该观察者观察来自 Room db 的列表数据的变化。它是这样工作的 - FragmentA
有列表 RecyclerView
并且当用户点击一个项目时,它会打开(替换)另一个 FragmentB
这是一个列表详细信息片段,用户可以在其中编辑列表详细信息项目并保存它(在数据库中更新),LiveData
将完成它的工作并更新列表。但是当我按下后退按钮时,FragmentA
的视图被重新创建并且另一个相同的观察者被订阅,如下面的代码所示 -
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupUI(view);
viewModel.getInspections().observe(this, inspectionsList -> {
setUpMainAdapter(inspectionsList); //setting Recyclerview adapter on recyclerview.
})
}
我找到了这个问题的解决方案in this article,它被写成使用getViewLifecycleOwner()
而不是this
,这样当片段视图层次结构改变时观察者也被取消订阅.
现在我的问题是,如果我从 FragmentB
返回到 FragmentA
,setUpMainAdapter()
会再次被调用,并且会在 recyclerview 上设置一个新的适配器。当我检查旧的适配器实例是否仍然存在时。如果我这样做 adapter.notifyItemChanged(position)
它不起作用并且 recyclerview 没有任何显示(因为视图已重新创建)。那么,在这里设置 recyclerview 的适配器是正确的方法吗?因为一次又一次地设置主适配器并且不能使用适配器的通知方法来更新一个项目感觉很奇怪。
use
getViewLifecycleOwner()
instead of this so that the observers are also unsubscribed when the fragment view hierarchy is changed.
这是根本。当你在 RxJava 等其他框架中注册观察者时,你总是需要最终取消订阅它。使用 LiveData,生命周期所有者会为您做这件事。但是当你使用 this
作为生命周期所有者时,观察者只会在片段被销毁时被删除,但它们不会在视图被销毁时被删除!所以你最终会有多个观察者引用被破坏的视图,这会造成内存泄漏。
So, is setting up the adapter to the recyclerview is the right approach here?
我通常在 onViewCreated
中创建我的适配器,但我认为如果您确保在新的 RecyclerView 上再次设置它,您应该可以重新使用旧的适配器。