将 BottomNavigationView 与导航组件一起使用时,如何防止重新创建片段?

Bin*_*ary 11 android fragment android-fragments bottomnavigationview android-architecture-navigation

我有一个应用程序,一个活动,带有 BottomNavigationView 和 Fragment:

\n
<?xml version="1.0" encoding="utf-8"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"\n    xmlns:app="http://schemas.android.com/apk/res-auto"\n    android:layout_width="match_parent"\n    android:layout_height="match_parent">\n\n    <com.google.android.material.bottomnavigation.BottomNavigationView\n        android:id="@+id/nav_view"\n        android:layout_width="match_parent"\n        android:layout_height="wrap_content"\n        app:layout_constraintBottom_toBottomOf="parent"\n        app:layout_constraintEnd_toEndOf="parent"\n        app:layout_constraintStart_toStartOf="parent"\n        app:menu="@menu/bottom_nav_menu" />\n\n    <fragment\n        android:id="@+id/nav_host_fragment_activity_main"\n        android:name="androidx.navigation.fragment.NavHostFragment"\n        android:layout_width="match_parent"\n        android:layout_height="0dp"\n        app:defaultNavHost="true"\n        app:layout_constraintBottom_toTopOf="@id/nav_view"\n        app:layout_constraintLeft_toLeftOf="parent"\n        app:layout_constraintRight_toRightOf="parent"\n        app:layout_constraintTop_toTopOf="parent"\n        app:navGraph="@navigation/mobile_navigation" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n
Run Code Online (Sandbox Code Playgroud)\n

四个片段,我在 MainActivity 中像这样导航:

\n
        val navController = findNavController(R.id.nav_host_fragment_activity_main)\n        binding.navView.setupWithNavController(navController)\n\n        binding.navView.setOnNavigationItemSelectedListener { item ->\n            when (item.itemId) {\n                R.id.navigation_fra1 -> {\n                    findNavController(R.id.nav_host_fragment_activity_main).navigate(R.id.Fragment)\n                }\n                R.id.navigation_fra2 -> {\n                    findNavController(R.id.nav_host_fragment_activity_main).navigate(R.id.Fragment2)\n                }\n                R.id.navigation_fra3 -> {\n                    findNavController(R.id.nav_host_fragment_activity_main).navigate(R.id.Fragment3)\n                }\n                R.id.navigation_fra4 -> {\n                    findNavController(R.id.nav_host_fragment_activity_main).navigate(R.id.Fragment4)\n                }\n            }\n            true\n        }\n
Run Code Online (Sandbox Code Playgroud)\n

片段都是相同的,但从 Firebase 数据库中提取不同的数据:

\n
class Fragment : Fragment() {\n    private var _binding: FragmentBinding? = null\n    private val binding get() = _binding!!\n    private lateinit var arrayList: ArrayList<FireItems>\n \n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        _binding = FragmentBinding.inflate(inflater, container, false)\n        val view = binding.root\n   \n        arrayList = ArrayList()\n\n        val database = Firebase.database\n        val myRef = database.getReference("items")\n        myRef.addValueEventListener(object : ValueEventListener {\n            @SuppressLint("NotifyDataSetChanged")\n            override fun onDataChange(dataSnapshot: DataSnapshot) {\n                val value = dataSnapshot.value\n                arrayList.clear()\n                Log.d("mDatabase", "Value is: $value")\n                for (postSnapshot in dataSnapshot.children) {\n\n                    arrayList.add(FireItems(postSnapshot.child("image").value.toString(), postSnapshot.child("name").value.toString(), postSnapshot.child("description").value.toString()))\n                    if (!arrayList.isNullOrEmpty()) {\n                        binding.apply {\n                            progressCircular.visibility = View.GONE\n                            recyclerView.setHasFixedSize(true)\n                            val adapter = FireRecyclerViewAdapter(requireActivity(), arrayList)\n                            recyclerView.layoutManager = GridLayoutManager(requireActivity(), 2)\n                            recyclerView.adapter = adapter\n                        }\n                    }\n                }\n\n            }\n\n            override fun onCancelled(error: DatabaseError) {\n                Log.w("mDatabase", "Failed to read value.", error.toException())\n            }\n        })\n\n        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {\n            override fun handleOnBackPressed() {}\n        })\n\n        return view\n    }\n\n    override fun onDestroyView() {\n        super.onDestroyView()\n        _binding = null\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我需要这样做,以便当我通过 BottomNavigationView 从一个片段移动到另一个片段时,不会每次都重新创建片段。因为,首先,如果列表中有很多元素,我不希望每次都滚动整个回收器,其次,就我而言,每次拉动数据库是不正确的知道。\n请告诉我如何做得更好?

\n