使用导航组件在 BottomNavigationView 中传递参数
Passing arguments in BottomNavigationView with navigation Component
我目前正在使用新的(对我来说)导航组件编写一个应用程序。我已经掌握了使用单个导航图在我的应用程序中导航的基础知识,我有一个带有 BottomNavigationView 的片段,其中有 3 个单独的片段,我已经设法更新它以使用导航组件(到目前为止我的问题)使用 ID 与导航项匹配的菜单。我以前使用 newInstance 方法将 bundle 传递给 onCreate 的片段显然现在没有使用,但我仍然需要将 bundle 传递给我的片段。
我找不到任何这样做的例子,因为片段是隐式创建的。
我的代码结构为 ClientFragment,它是导航抽屉等的宿主片段;
class ClientFragment : Fragment() {
private val viewModel: ClientViewModel by viewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_client, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
toolbar_client.title = viewModel.client.name
toolbar_client.setNavigationOnClickListener { Navigation.findNavController(view).navigateUp() }
}
}
这个class之前对我的fragments进行onclick监听,用newInstance方法里面的工具viewModel.client.
我在nav_graph中的片段都是相似的。第一个片段;
class ClientDetailsFragment : Fragment() {
private val viewModel: ClientViewModel by viewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_client_details, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
initClientDetails()
}
private fun initClientDetails() {
// text_client_details_name.text = viewModel.client.name
// text_client_details_account_number.text = viewModel.client.accountNumber
// text_client_details_mobile_number.text = viewModel.client.mobileNumber
// text_client_details_landline_number.text = viewModel.client.landlineNumber
// text_client_details_email.text = viewModel.client.email
// text_client_details_address.text = "NOT YET IMPLEMENTED"
//
// text_client_description_body.text = viewModel.client.description
// text_client_system_details_body.text = viewModel.client.systemDetails
}
}
应用程序在注释掉的行崩溃;
// viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
我的导航图和菜单是;
导航图;
<?xml version="1.0" encoding="utf-8"?>
<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/client_nav_graph"
app:startDestination="@id/clientDetailsFragment">
<fragment
android:id="@+id/clientCustomersFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientCustomersFragment"
android:label="ClientCustomersFragment"
tools:layout="@layout/fragment_client_customers" />
<fragment
android:id="@+id/clientDetailsFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientDetailsFragment"
android:label="ClientDetailsFragment"
tools:layout="@layout/fragment_client_details"/>
<fragment
android:id="@+id/clientJobHistoryFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientJobHistoryFragment"
android:label="ClientJobHistoryFragment"
tools:layout="@layout/fragment_client_job_history" />
</navigation>
菜单;
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/clientDetailsFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Details"/>
<item
android:id="@+id/clientJobHistoryFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Job History"/>
<item
android:id="@+id/clientCustomersFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Customers"/>
</menu>
我发现您可以将参数添加到导航图中,但没有找到关于在这种特定情况下将参数放在哪里的信息,我还知道在使用 .navigate 导航时能够手动添加包。
我有没有办法在我的 ClientFragment 中为每个片段设置参数
viewModel.client
更新:
我的争论问题是通过使用在 BottomNavigationView 中的所有片段之间共享的视图模型解决的(我在向朋友输入问题时意识到这一点)和导航本身 我将其添加到 ClientFragment ;
bottom_nav_client.setupWithNavController(
Navigation.findNavController(
view.findViewById<View>(R.id.fl_client_nav_container)
)
)
和我的 xml fragment_client;
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_client"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="?attr/NavigationBackIconLight"
app:titleTextColor="@color/white" />
<fragment
android:id="@+id/fl_client_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_client"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_client"
app:navGraph="@navigation/client_nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_client"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?android:attr/windowBackground"
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@drawable/bottom_nav_color"
app:itemTextColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/client_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
这与上面显示的相同导航图和菜单相结合。
导航架构组件 documentation 展示了如何定义目标参数,在您的具体情况下,您应该创建一个自定义 Parcelable
class (即 Client
)并将其作为相应片段的参数。
<fragment
android:id="@+id/clientCustomersFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientCustomersFragment"
android:label="ClientCustomersFragment"
tools:layout="@layout/fragment_client_customers" >
<action
android:id="@+id/client_to_details"
app:destination="@+id/clientDetailsFragment" />
</fragment>
<fragment
android:id="@+id/clientDetailsFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientDetailsFragment"
android:label="ClientDetailsFragment"
tools:layout="@layout/fragment_client_details">
<argument
android:name="client"
app:argType="com.management.engineering.alarm.alarmengineermanagement.features.client.Client" />
</fragment>
'androidx.navigation.safeargs'
gradle 插件将生成 classes ClientToDetails
和 ClientDetailsFragmentArgs
可用于 pass.retrieve 参数 client
.
来源
val client: Client = TODO()
val navController: NavController = TODO()
navController.navigate(ClientToDetails(client))
目的地
val client = ClientDetailsFragmentArgs.fromBundle(arguments).client
此 Codelab 正是您想要做的事情:
https://codelabs.developers.google.com/codelabs/android-navigation/index.html?index=..%2F..index#0
文档:https://developer.android.com/topic/libraries/architecture/navigation/
接受的答案中提到的代码实验室没有提到将参数传递给 BottomNavigationView 中的片段。
用自定义的覆盖 setupWithNavController() 设置的 OnNavigationItemSelectedListener:
val args = Bundle()
bottomNavigationView.setupWithNavController(navController)
bottomNavigationView.setOnNavigationItemSelectedListener { item ->
navController.navigate(item.itemId, args)
true
}
我目前正在使用新的(对我来说)导航组件编写一个应用程序。我已经掌握了使用单个导航图在我的应用程序中导航的基础知识,我有一个带有 BottomNavigationView 的片段,其中有 3 个单独的片段,我已经设法更新它以使用导航组件(到目前为止我的问题)使用 ID 与导航项匹配的菜单。我以前使用 newInstance 方法将 bundle 传递给 onCreate 的片段显然现在没有使用,但我仍然需要将 bundle 传递给我的片段。
我找不到任何这样做的例子,因为片段是隐式创建的。
我的代码结构为 ClientFragment,它是导航抽屉等的宿主片段;
class ClientFragment : Fragment() {
private val viewModel: ClientViewModel by viewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_client, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
toolbar_client.title = viewModel.client.name
toolbar_client.setNavigationOnClickListener { Navigation.findNavController(view).navigateUp() }
}
}
这个class之前对我的fragments进行onclick监听,用newInstance方法里面的工具viewModel.client.
我在nav_graph中的片段都是相似的。第一个片段;
class ClientDetailsFragment : Fragment() {
private val viewModel: ClientViewModel by viewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_client_details, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
initClientDetails()
}
private fun initClientDetails() {
// text_client_details_name.text = viewModel.client.name
// text_client_details_account_number.text = viewModel.client.accountNumber
// text_client_details_mobile_number.text = viewModel.client.mobileNumber
// text_client_details_landline_number.text = viewModel.client.landlineNumber
// text_client_details_email.text = viewModel.client.email
// text_client_details_address.text = "NOT YET IMPLEMENTED"
//
// text_client_description_body.text = viewModel.client.description
// text_client_system_details_body.text = viewModel.client.systemDetails
}
}
应用程序在注释掉的行崩溃;
// viewModel.client = arguments?.getParcelable(ARG_CLIENT)!!
我的导航图和菜单是;
导航图;
<?xml version="1.0" encoding="utf-8"?>
<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/client_nav_graph"
app:startDestination="@id/clientDetailsFragment">
<fragment
android:id="@+id/clientCustomersFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientCustomersFragment"
android:label="ClientCustomersFragment"
tools:layout="@layout/fragment_client_customers" />
<fragment
android:id="@+id/clientDetailsFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientDetailsFragment"
android:label="ClientDetailsFragment"
tools:layout="@layout/fragment_client_details"/>
<fragment
android:id="@+id/clientJobHistoryFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientJobHistoryFragment"
android:label="ClientJobHistoryFragment"
tools:layout="@layout/fragment_client_job_history" />
</navigation>
菜单;
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/clientDetailsFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Details"/>
<item
android:id="@+id/clientJobHistoryFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Job History"/>
<item
android:id="@+id/clientCustomersFragment"
android:icon="@drawable/ic_launcher_foreground"
android:title="Customers"/>
</menu>
我发现您可以将参数添加到导航图中,但没有找到关于在这种特定情况下将参数放在哪里的信息,我还知道在使用 .navigate 导航时能够手动添加包。
我有没有办法在我的 ClientFragment 中为每个片段设置参数
viewModel.client
更新:
我的争论问题是通过使用在 BottomNavigationView 中的所有片段之间共享的视图模型解决的(我在向朋友输入问题时意识到这一点)和导航本身 我将其添加到 ClientFragment ;
bottom_nav_client.setupWithNavController(
Navigation.findNavController(
view.findViewById<View>(R.id.fl_client_nav_container)
)
)
和我的 xml fragment_client;
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_client"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="?attr/NavigationBackIconLight"
app:titleTextColor="@color/white" />
<fragment
android:id="@+id/fl_client_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_client"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_client"
app:navGraph="@navigation/client_nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_client"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?android:attr/windowBackground"
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@drawable/bottom_nav_color"
app:itemTextColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/client_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
这与上面显示的相同导航图和菜单相结合。
导航架构组件 documentation 展示了如何定义目标参数,在您的具体情况下,您应该创建一个自定义 Parcelable
class (即 Client
)并将其作为相应片段的参数。
<fragment
android:id="@+id/clientCustomersFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientCustomersFragment"
android:label="ClientCustomersFragment"
tools:layout="@layout/fragment_client_customers" >
<action
android:id="@+id/client_to_details"
app:destination="@+id/clientDetailsFragment" />
</fragment>
<fragment
android:id="@+id/clientDetailsFragment"
android:name="com.management.engineering.alarm.alarmengineermanagement.features.client.ClientDetailsFragment"
android:label="ClientDetailsFragment"
tools:layout="@layout/fragment_client_details">
<argument
android:name="client"
app:argType="com.management.engineering.alarm.alarmengineermanagement.features.client.Client" />
</fragment>
'androidx.navigation.safeargs'
gradle 插件将生成 classes ClientToDetails
和 ClientDetailsFragmentArgs
可用于 pass.retrieve 参数 client
.
来源
val client: Client = TODO()
val navController: NavController = TODO()
navController.navigate(ClientToDetails(client))
目的地
val client = ClientDetailsFragmentArgs.fromBundle(arguments).client
此 Codelab 正是您想要做的事情: https://codelabs.developers.google.com/codelabs/android-navigation/index.html?index=..%2F..index#0
文档:https://developer.android.com/topic/libraries/architecture/navigation/
接受的答案中提到的代码实验室没有提到将参数传递给 BottomNavigationView 中的片段。
用自定义的覆盖 setupWithNavController() 设置的 OnNavigationItemSelectedListener:
val args = Bundle()
bottomNavigationView.setupWithNavController(navController)
bottomNavigationView.setOnNavigationItemSelectedListener { item ->
navController.navigate(item.itemId, args)
true
}