Android 导航项更改不会发生';t更新回收器视图
我有一个带导航视图的抽屉布局活动。这些项目包括“主页”、“关于我们”、“事件日程表”等。事件日程表有一个片段,其中包含底部导航抽屉和视图寻呼机。只有2个片段附加到viewpager-第1天计划和第2天计划。同样,底部导航中只有2项。每个片段都有一个recycler视图,我在其中显示事件列表及其日期和时间 当我启动应用程序时,主页片段会按预期弹出。我进入导航抽屉,点击“活动日程”。“回收器”视图将加载数据。我可以在浏览页面上滑动。一切正常 但现在当我点击“关于我们”时,那个片段像往常一样打开了。当我重新打开“Events And Schedule”时,recycler视图不会显示任何列表项。它在我第一次单击它时起作用,但在第二次、第三次等等时不起作用 EventsFragment.kt(带有viewpager和底部导航的主要片段): EventDayFragment.kt(viewpager中的片段): 在我的代码中,我注意到在EventDayFragment.kt中,onViewCreated函数只被调用一次。这就是为什么recyclerview只能工作一次。我该如何解决这个问题 编辑Android 导航项更改不会发生';t更新回收器视图,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我有一个带导航视图的抽屉布局活动。这些项目包括“主页”、“关于我们”、“事件日程表”等。事件日程表有一个片段,其中包含底部导航抽屉和视图寻呼机。只有2个片段附加到viewpager-第1天计划和第2天计划。同样,底部导航中只有2项。每个片段都有一个recycler视图,我在其中显示事件列表及其日期和时间 当我启动应用程序时,主页片段会按预期弹出。我进入导航抽屉,点击“活动日程”。“回收器”视图将加载数据。我可以在浏览页面上滑动。一切正常 但现在当我点击“关于我们”时,那个片段像往常一样打开了。当
class EventDayFragment : Fragment(R.layout.fragment_event_day) {
companion object {
...
var isAlive = false
}
override fun onAttach(context: Context) {
super.onAttach(context)
isAlive = true
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding = FragmentEventDayBinding.bind(view)
val day = arguments?.getInt(PARAM_1)!!
loadDataToRecyclerView(day)
}
private fun loadDataToRecyclerView(day: Int) {
... // Same as before
}
override fun onPause() {
super.onPause()
isAlive = false
}
}
我添加了一个静态布尔变量,以了解片段是否正在运行。在EventsFragment中,我将此代码添加到setupViewPager()
:
完成此编辑后,我收到以下错误:EventDayFragment未附加到上下文。原因:
这是正确的EventDayFragment视图没有被销毁,因此onViewCreated只在第一次调用一次,数据将正常工作,并且EventsSchedule的子片段被创建(据我所知,EventSchedule包含viewPager和两个子片段Day 1 schedule和Day 2 schedule),但是当您单击About我们时,EventsSchedule片段本身不会被销毁,但这不一定适用于它的子项(第1天计划和第2天计划),子项可能会被销毁,当它们在第二次创建时,它们将找不到数据(因为父项不像它们那样被销毁)
如何解决这个问题:
我认为有很多解决方案:
问题是,每次我创建父片段的视图时,子片段的
onViewCreated(view:view,savedInstanceState:Bundle?
并没有被调用。这是因为这一行代码:
binding.viewPagerScheduleDay.adapter=EventDayPagerAdapter(requireAction().supportFragmentManager)
传递活动的FragmentManager并没有告诉应用程序每次都创建子片段的视图
相反,我们必须添加以下代码:
binding.viewPagerScheduleDay.adapter=EventDayPagerAdapter(childFragmentManager)
这很好用 多谢各位。我了解父母的情况,但不一定了解孩子。我知道将
loadDataToRecyclerView(day)
放在onResume()中是正确的。但是,我不明白您在第一个解决方案中的意思。欢迎光临,乐意帮助。第一索尔:你有两个碎片,对吗?两者都有onViewCreated,第一种解决方案说,找到一种方法将数据加载到子片段的onViewCreated中的recyclerview,可以通过它们之间的回调接口请求父片段执行此操作(因为正如u所说,不会调用父片段的onViewCreated,但会调用子片段的onViewCreated)我更推荐这种解决方案,因为通过这种方式,您可以确保数据不会加载到recyclerview,除非创建子视图。如果使用回调接口,我需要获取片段的实例。由于片段是通过viewpager显示的,我将如何获取片段?R.id类没有子片段的id,我不知道如何用它注册任何标记。我还将loadDataToRecyclerView(day)
移动到onResume()
方法,但我仍然只看到底部导航,没有看到RecyclerViewWTO使用getParentFragment()获取父片段(但请确保不要在onViewCreated之前调用它,因为它将为空)
class EventDayFragment : Fragment(R.layout.fragment_event_day) {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding = FragmentEventDayBinding.bind(view)
val day = arguments?.getInt(PARAM_1)!!
loadDataToRecyclerView(day)
}
private fun loadDataToRecyclerView(day: Int) {
Database.getEventsFromDay(day) { events ->
events?.let {
val eventAdapter = EventScheduleRecyclerAdapter(requireContext(), it)
binding.recyclerViewEventsSchedule.apply {
layoutManager = StaggeredGridLayoutManager(2, VERTICAL)
adapter = eventAdapter
setHasFixedSize(true)
}
} ?: requireContext().toast("Error Encountered in collecting data.")
}
}
}
class EventDayFragment : Fragment(R.layout.fragment_event_day) {
companion object {
...
var isAlive = false
}
override fun onAttach(context: Context) {
super.onAttach(context)
isAlive = true
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding = FragmentEventDayBinding.bind(view)
val day = arguments?.getInt(PARAM_1)!!
loadDataToRecyclerView(day)
}
private fun loadDataToRecyclerView(day: Int) {
... // Same as before
}
override fun onPause() {
super.onPause()
isAlive = false
}
}
private fun setupViewPager() {
val eventDayFragmentAdapter = EventDayFragmentAdapter(
requireActivity().supportFragmentManager
)
binding.viewPagerScheduleDay.adapter = eventDayFragmentAdapter
val fragment = eventDayFragmentAdapter.getItem(binding.viewPagerScheduleDay.currentItem)
if (EventDayFragment.isAlive)
fragment.loadDataToRecyclerView(binding.viewPagerScheduleDay.currentItem + 1)
binding.bottomNav.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.mDay1 -> binding.viewPagerScheduleDay.currentItem = 0
R.id.mDay2 -> binding.viewPagerScheduleDay.currentItem = 1
}
true
}
}