我正在使用导航组件在我的应用程序中导航。它在片段内工作正常,但无法在包含实际导航主机的活动中找到导航主机。
我试图在用户点击FAB时打开一个新片段,我将其包含在Main活动的XML中。当我调用findNavController()时,它无法找到控制器。导航主机控制器采用XML布局。我无法理解为什么它找不到它。
主要信息
class MainActivity : AppCompatActivity(), OnActivityComponentRequest {
override fun getTabLayout(): TabLayout {
return this.tabLayout
}
override fun getFap(): FloatingActionButton {
return this.floatingActionButton
}
private lateinit var tabLayout: TabLayout
private lateinit var floatingActionButton: FloatingActionButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
this.tabLayout = tabs
this.floatingActionButton = fab
fab.setOnClickListener {
it.findNavController().navigate(R.id.addNewWorkoutFragment)
}
}
}
Activity_main XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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"
tools:context=".domain.MainActivity"
android:animateLayoutChanges="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:text="Test 1"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<com.google.android.material.tabs.TabItem
android:text="Test 2"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/main_navigation" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchorGravity="right|top"
app:layout_anchor="@+id/bar"
android:src="@drawable/ic_add_black_24dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
尝试在活动的onStart
中设置Fab按钮的onClickListener,如onCreate
中的活动只是给视图充气并且没有设置NavHostController
。因此,如果您在onStart中设置onClickListener
活动将按预期工作。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
this.tabLayout = tabs
this.floatingActionButton = fab
}
override fun onStart() {
super.onStart()
floatingActionButton.setOnClickListener {
it.findNavController().navigate(R.id.addNewWorkoutFragment)
}
}
原来那个持有导航控制器的活动......没有导航组件。
解决方案是手动将NavController设置为活动中包含的每个视图。
val navController = findNavController(R.id.nav_host_fragment)
Navigation.setViewNavController(fab, navController)
现在这可行:
fab.setOnClickListener {
it.findNavController().navigate(R.id.addNewWorkoutFragment)
}
我仍然不明白为什么它的工作方式如此有效,所以任何解释都会受到欢迎:)
截至目前,Android API根本没有多大意义。
资料来源:Navigate to fragment on FAB click (Navigation Architecture Components)