Android 导航项更改不会发生';t更新回收器视图

Android 导航项更改不会发生';t更新回收器视图,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我有一个带导航视图的抽屉布局活动。这些项目包括“主页”、“关于我们”、“事件日程表”等。事件日程表有一个片段,其中包含底部导航抽屉和视图寻呼机。只有2个片段附加到viewpager-第1天计划和第2天计划。同样,底部导航中只有2项。每个片段都有一个recycler视图,我在其中显示事件列表及其日期和时间 当我启动应用程序时,主页片段会按预期弹出。我进入导航抽屉,点击“活动日程”。“回收器”视图将加载数据。我可以在浏览页面上滑动。一切正常 但现在当我点击“关于我们”时,那个片段像往常一样打开了。当

我有一个带导航视图的抽屉布局活动。这些项目包括“主页”、“关于我们”、“事件日程表”等。事件日程表有一个片段,其中包含底部导航抽屉和视图寻呼机。只有2个片段附加到viewpager-第1天计划和第2天计划。同样,底部导航中只有2项。每个片段都有一个recycler视图,我在其中显示事件列表及其日期和时间

当我启动应用程序时,主页片段会按预期弹出。我进入导航抽屉,点击“活动日程”。“回收器”视图将加载数据。我可以在浏览页面上滑动。一切正常

但现在当我点击“关于我们”时,那个片段像往常一样打开了。当我重新打开“Events And Schedule”时,recycler视图不会显示任何列表项。它在我第一次单击它时起作用,但在第二次、第三次等等时不起作用

EventsFragment.kt(带有viewpager和底部导航的主要片段):

EventDayFragment.kt(viewpager中的片段):

在我的代码中,我注意到在EventDayFragment.kt中,onViewCreated函数只被调用一次。这就是为什么recyclerview只能工作一次。我该如何解决这个问题

编辑

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()中,向父片段请求数据,并在子片段本身中创建loadDataToRecyclerView(day)

  • (快速但不推荐)尝试将loadDataToRecyclerView(天)移动到 onResume()而不是onViewCreated()


  • 问题是,每次我创建父片段的视图时,子片段的
    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
            }
        }