【发布时间】:2022-10-12 22:27:03
【问题描述】:
我已经使用 NavController 实现了 BottomNavigationView,但片段会在每次点击时不断重新加载,即使更新了新的导航库。我也试过 setOnNavigationItemReselectedListener 但它不会触发任何东西。我究竟做错了什么 ? 我知道这个问题已经被问过不止一次了,但我觉得我都试过了,但都没有奏效。我希望我可以避免使用旧库或使用样板解决方案来恢复我的代码。 这是我的代码:
build.gradle (:app)
implementation 'androidx.navigation:navigation-runtime-ktx:2.5.2' implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2' implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'家庭活动.kt
class HomeActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener, Serializable { private lateinit var binding: ActivityHomeBinding private lateinit var navController: NavController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding= ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) val navHostFragment = supportFragmentManager.findFragmentById(R.id.home_container) as NavHostFragment navController = navHostFragment.navController binding.bottomNavigation.setupWithNavController(navController) } }活动主页.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start" tools:context=".HomeActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/home_container" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="0dp" app:defaultNavHost="true" app:layout_constraintBottom_toTopOf="@+id/bottom_navigation" app:layout_constraintTop_toBottomOf="@+id/appbar_layout" app:navGraph="@navigation/nav_main" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" app:menu="@menu/bottom_navigation_menu" app:layout_constraintTop_toBottomOf="@+id/home_container" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.5"/> </RelativeLayout>nav_main.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_main" app:startDestination="@id/firstFragment"> <fragment android:id="@+id/firstFragment" android:name="com.projectName.ui.main.ContactsFragment" tools:layout="@layout/fragment_contacts" /> <fragment android:id="@+id/secondFragment" android:name="com.projectName.SearchFragment" android:label="@string/search" tools:layout="@layout/search_fragment" /> <fragment android:id="@+id/thirdFragment" android:name="com.projectName.ui.main.NotificationsFragment" tools:layout="@layout/notifications_fragment" /> <fragment android:id="@+id/fourthFragment" android:name="com.projectName.chat.ChatFragment" tools:layout="@layout/fragment_main_page" /> </navigation>bottom_navigation_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/firstFragment" android:enabled="true" android:icon="@drawable/ic_baseline_contacts_24" android:title="" app:labelVisibilityMode="unlabeled"/> <item android:id="@+id/secondFragment" android:enabled="true" android:icon="@drawable/ic_search_white_24dp" android:title="" app:labelVisibilityMode="unlabeled"/> <item android:id="@+id/thirdFragment" android:enabled="true" android:icon="@drawable/ic_baseline_notifications_none_24" android:title="" app:labelVisibilityMode="unlabeled"/> <item android:id="@+id/fourthFragment" android:enabled="true" android:icon="@drawable/ic_message_white_24dp" android:title="" app:labelVisibilityMode="unlabeled"/> </menu>碎片
class NotificationsFragment : Fragment() { companion object { fun newInstance() = NotificationsFragment() } private lateinit var viewModel: NotificationsViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { viewModel = ViewModelProvider(this).get(NotificationsViewModel::class.java) return inflater.inflate(R.layout.notifications_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) }我还给每个布局一个 ID,就像 saveInstateState 的文档所建议的那样。
谢谢你。
编辑
我找不到解决问题的方法,所以我将 BottomNavigationView 与 ViewPager2 一起使用:
HomePagerAdapter.kt
private val TAB_TITLES = arrayOf( Constants.CONTACTS, Constants.SEARCH, Constants.NOTIFICATIONS, Constants.CHATS ) class HomePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { override fun getItemCount(): Int = TAB_TITLES.size override fun createFragment(position: Int): Fragment { return if (getPageTitle(position) == Constants.CONTACTS) { ContactsFragment.newInstance() } else if (getPageTitle(position) == Constants.SEARCH) { SearchFragment.newInstance() } else if (getPageTitle(position) == Constants.NOTIFICATIONS) { NotificationsFragment.newInstance() } else { ChatsFragment.newInstance() } } private fun getPageTitle(position: Int): String { return TAB_TITLES[position] } }家庭活动.kt
class HomeActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener, Serializable, SearchFragment.OnPersonSelectedListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) val homePagerAdapter = HomePagerAdapter(this) val viewPager: ViewPager2 = findViewById(R.id.home_view_pager) viewPager.adapter = homePagerAdapter viewPager.isUserInputEnabled = false viewPager.offscreenPageLimit = 1 viewPager.overScrollMode = ViewPager2.OVER_SCROLL_NEVER findViewById<BottomNavigationView>(R.id.bottom_navigation) .setOnItemSelectedListener { when (it.itemId) { R.id.firstFragment -> { viewPager.setCurrentItem(0, false) return@setOnItemSelectedListener true } R.id.secondFragment -> { viewPager.setCurrentItem(1, false) return@setOnItemSelectedListener true } R.id.thirdFragment -> { viewPager.setCurrentItem(2, false) return@setOnItemSelectedListener true } R.id.fourthFragment -> { viewPager.setCurrentItem(3, false) return@setOnItemSelectedListener true } else -> return@setOnItemSelectedListener false } } } }活动主页.xml
<androidx.viewpager2.widget.ViewPager2 android:id="@+id/home_view_pager" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/bottom_navigation" app:layout_constraintTop_toBottomOf="@+id/appbar_layout" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" app:menu="@menu/bottom_navigation_menu" app:layout_constraintTop_toBottomOf="@+id/home_view_pager" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.5"/>
【问题讨论】:
标签: android kotlin android-fragments bottomnavigationview android-navigation-graph