如何使用底部导航视图和 Android 导航组件将参数传递给片段?
How to pass arguments to a fragment using bottom navigation view and Android Navigation component?
是否可以使用底部导航视图和导航组件在片段中传递和访问参数?
我正在使用一个 activity 和许多片段的方法,其中我的顶级片段需要一个参数(通常通过 newInstance 生成的方法完成)。我看过 Navigation component developer guide 和 codelab,但它只提到使用 safeargs 并在目的地和操作中添加参数标签。
这是我的导航图:
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/homeFragment">
<fragment android:id="@+id/homeFragment"
android:name="uk.co.homeready.homeready.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<!--Do I create an argument block here?-->
</fragment>
<fragment android:id="@+id/calculatorFragment"
android:name="uk.co.homeready.homeready.CalculatorFragment"
android:label="fragment_calculator"
tools:layout="@layout/fragment_calculator"/>
<fragment android:id="@+id/resourcesFragment"
android:name="uk.co.homeready.homeready.ResourcesFragment"
android:label="fragment_resources"
tools:layout="@layout/fragment_resources"/>
</navigation>
底部导航视图菜单:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home"/>
<item
android:id="@+id/calculatorFragment"
android:icon="@drawable/ic_baseline_attach_money_24px"
android:title="@string/title_calculator"/>
<item
android:id="@+id/resourcesFragment"
android:icon="@drawable/ic_baseline_library_books_24px"
android:title="@string/title_resources"/>
</menu>
主要活动:
override fun onCreate(savedInstanceState: Bundle?) {
...
val navController = Navigation.findNavController(this,
R.id.nav_host_fragment)
bottom_navigation.setupWithNavController(navController)
....
}
activity_main.xml
<android.support.constraint.ConstraintLayout>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
app:menu="@menu/bottom_navigation"/>
</android.support.constraint.ConstraintLayout>
主页片段
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val argument = //TODO access argument here
...
}
如果我没理解错的话,您想将参数传递给与菜单项相关联的目的地。尝试在 activity onCreate 方法中使用 'OnDestinationChangedListener',如下所示:
navController.addOnDestinationChangedListener { controller, destination, arguments ->
when(destination.id) {
R.id.homeFragment -> {
val argument = NavArgument.Builder().setDefaultValue(6).build()
destination.addArgument("Argument", argument)
}
}
}
更新:
如果您希望您的起始目的地接收默认参数,则实现应该有所不同。
首先,从 'NavHostFragment' xml 标签中删除 'app:navGraph="@navigation/nav_graph"'。
然后,在您的 activity onCreate 中,您需要膨胀图形:
val navInflater = navController.navInflater
val graph = navInflater.inflate(R.navigation.nav_graph)
然后将您的参数添加到图表(此参数将附加到起始目的地)
val navArgument1=NavArgument.Builder().setDefaultValue(1).build()
val navArgument2=NavArgument.Builder().setDefaultValue("Hello").build()
graph.addArgument("Key1",navArgument1)
graph.addArgument("Key2",navArgument2)
然后将图形附加到 NavController:
navController.graph=graph
现在您的第一个目的地应该收到附加参数。
正确的做法确实是在目的地设置 <argument>
街区。
<fragment android:id="@+id/homeFragment"
android:name="uk.co.homeready.homeready.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<argument
android:name="Argument"
android:defaultValue="value"
/>
</fragment>
这将自动使用默认值填充 Fragment 的参数,无需任何额外代码。从 Navigation 1.0.0-alpha09 开始,无论您是否使用 Safe Args Gradle 插件都是如此。
默认值对我不可用,因为我有动态菜单项,这些菜单项可能有多个具有不同参数的相同目的地。 (从服务器更改)
实施BottomNavigationView.OnNavigationItemSelectedListener:
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val fragmentId = item.itemId
val arguments = argumentsByFragmentId[fragmentId] // custom mutableMapOf<Int, Bundle?>() with arguments
navController().navigate(fragmentId, arguments)
return true
}
要使用它,您将通过替换侦听器来接管导航。这里的调用顺序很重要:
bottomNavigationView.setupWithNavController(navController)
bottomNavigationView.setOnNavigationItemSelectedListener(this)
是否可以使用底部导航视图和导航组件在片段中传递和访问参数?
我正在使用一个 activity 和许多片段的方法,其中我的顶级片段需要一个参数(通常通过 newInstance 生成的方法完成)。我看过 Navigation component developer guide 和 codelab,但它只提到使用 safeargs 并在目的地和操作中添加参数标签。
这是我的导航图:
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/homeFragment">
<fragment android:id="@+id/homeFragment"
android:name="uk.co.homeready.homeready.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<!--Do I create an argument block here?-->
</fragment>
<fragment android:id="@+id/calculatorFragment"
android:name="uk.co.homeready.homeready.CalculatorFragment"
android:label="fragment_calculator"
tools:layout="@layout/fragment_calculator"/>
<fragment android:id="@+id/resourcesFragment"
android:name="uk.co.homeready.homeready.ResourcesFragment"
android:label="fragment_resources"
tools:layout="@layout/fragment_resources"/>
</navigation>
底部导航视图菜单:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home"/>
<item
android:id="@+id/calculatorFragment"
android:icon="@drawable/ic_baseline_attach_money_24px"
android:title="@string/title_calculator"/>
<item
android:id="@+id/resourcesFragment"
android:icon="@drawable/ic_baseline_library_books_24px"
android:title="@string/title_resources"/>
</menu>
主要活动:
override fun onCreate(savedInstanceState: Bundle?) {
...
val navController = Navigation.findNavController(this,
R.id.nav_host_fragment)
bottom_navigation.setupWithNavController(navController)
....
}
activity_main.xml
<android.support.constraint.ConstraintLayout>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
app:menu="@menu/bottom_navigation"/>
</android.support.constraint.ConstraintLayout>
主页片段
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val argument = //TODO access argument here
...
}
如果我没理解错的话,您想将参数传递给与菜单项相关联的目的地。尝试在 activity onCreate 方法中使用 'OnDestinationChangedListener',如下所示:
navController.addOnDestinationChangedListener { controller, destination, arguments ->
when(destination.id) {
R.id.homeFragment -> {
val argument = NavArgument.Builder().setDefaultValue(6).build()
destination.addArgument("Argument", argument)
}
}
}
更新:
如果您希望您的起始目的地接收默认参数,则实现应该有所不同。 首先,从 'NavHostFragment' xml 标签中删除 'app:navGraph="@navigation/nav_graph"'。
然后,在您的 activity onCreate 中,您需要膨胀图形:
val navInflater = navController.navInflater
val graph = navInflater.inflate(R.navigation.nav_graph)
然后将您的参数添加到图表(此参数将附加到起始目的地)
val navArgument1=NavArgument.Builder().setDefaultValue(1).build()
val navArgument2=NavArgument.Builder().setDefaultValue("Hello").build()
graph.addArgument("Key1",navArgument1)
graph.addArgument("Key2",navArgument2)
然后将图形附加到 NavController:
navController.graph=graph
现在您的第一个目的地应该收到附加参数。
正确的做法确实是在目的地设置 <argument>
街区。
<fragment android:id="@+id/homeFragment"
android:name="uk.co.homeready.homeready.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<argument
android:name="Argument"
android:defaultValue="value"
/>
</fragment>
这将自动使用默认值填充 Fragment 的参数,无需任何额外代码。从 Navigation 1.0.0-alpha09 开始,无论您是否使用 Safe Args Gradle 插件都是如此。
默认值对我不可用,因为我有动态菜单项,这些菜单项可能有多个具有不同参数的相同目的地。 (从服务器更改)
实施BottomNavigationView.OnNavigationItemSelectedListener:
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val fragmentId = item.itemId
val arguments = argumentsByFragmentId[fragmentId] // custom mutableMapOf<Int, Bundle?>() with arguments
navController().navigate(fragmentId, arguments)
return true
}
要使用它,您将通过替换侦听器来接管导航。这里的调用顺序很重要:
bottomNavigationView.setupWithNavController(navController)
bottomNavigationView.setOnNavigationItemSelectedListener(this)