更新基本导航抽屉的参数 activity
Update an argument of a basic navigation drawer activity
上下文:
我想在他登录后将 userId 传递给片段 UserFragment。
我使用一个新项目 Android 输入“Navigation drawer activity”。
我使用 LiveData,所以当用户登录时,我的 livedata 的观察者从 MainActivity 更新 idUser。我还想更新我的导航组件中的片段参数...
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home,
R.id.userDetailItemNav,
R.id.dashboardItemNav), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
我的问题:
我只是想在导航时将 userId 的值作为参数传递给目的地(UserDetails 片段)...但我不想创建 onClickListner 并在包中传递参数。我只想使用导航组件解决方案,因此只需更改在我的导航组件中声明的片段的参数值
我在我的项目中添加了“安全参数”。
我在其中一个目标片段上添加了一个“theUserId”参数:
在mobile_navigation.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/mobile_navigation"
app:startDestination="@+id/dashboardItemNav">
<fragment (...) />
<fragment (...) />
<fragment
android:id="@+id/userDetailItemNav"
android:name="com.example.smart.ui.user.UserFragment"
tools:layout="@layout/fragment_user" >
<argument
android:name="theUserId"
app:argType="long"
android:defaultValue="-1L"
/>
</fragment>
</navigation>
在UserFragment.kt中:
// loading specifics arguments
val argument = arguments?.getLong("theUserId",999L)
Timber.i("userId from MainActivity: $argument")
我试过的:
我在 MainActivity.kt 的 onCreate() 中的 LiveData 观察器是:
viewModel.user.observe(this, Observer { user ->
if (user != null) {
userId = user.id
// TODO: here, change the value of my navigation argument theUserId
}
我试图在我的 LiveData Observer 中添加一个 addOnDestinationChangedListner(但它增加了 Listner)。我也尝试在观察者之后直接放在我的 MainActivity 的 OnCreate 中(似乎更好):
navController.addOnDestinationChangedListener {_, destination, arguments ->
if (destination.id == R.id.userDetailItemNav) {
userId?.let {
val argument = NavArgument.Builder()
.setDefaultValue(it)
.build()
}
}
}
...但是仅在第二次单击 我的 UserDetail 片段的导航项后,userId 值才会更新 。我不明白为什么。
我认为这段代码最好放在我的 Livedata 观察器中:
var userId = 75 // 75 is from my Livedata for example
var myArgs = UserFragmentArgs.Builder().setTheUserId(userId).build()
...但我不知道如何处理 myArgs...如何使用它,如何将它注入导航组件以便下次我单击抽屉项目“Detail User ”,我的参数“theUserId”在片段 UserFragment 中被很好地修改和检索。
感谢您的帮助。
我相信 Documentation 中的示例很容易适用于您的用例。
它不干净,但这是一个有效的解决方案。不幸的是,这个解决方案并没有完全尊重导航组件的精神...
在MainActivity.kt中,在onCreate()函数中:
viewModel.user.observe(this, Observer { user ->
if (user != null) {
userId = user.id
}
}
// (...)
navView.setNavigationItemSelectedListener { menuItem ->
drawerLayout.closeDrawers() // close drawer when item is tapped
val bundle = bundleOf("theUserId" to userId)
when (menuItem.itemId) {
R.id.userDetailItemNav -> {
navController.navigate(menuItem.itemId, bundle)
}
else -> { // for other destination without parameter
navController.navigate(menuItem.itemId)
}
}
true
}
如果您有更好的主意(即能够直接在观察者中更改 UserId 参数的值),我会采纳您的建议很高兴 !.
上下文: 我想在他登录后将 userId 传递给片段 UserFragment。 我使用一个新项目 Android 输入“Navigation drawer activity”。 我使用 LiveData,所以当用户登录时,我的 livedata 的观察者从 MainActivity 更新 idUser。我还想更新我的导航组件中的片段参数...
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_home,
R.id.userDetailItemNav,
R.id.dashboardItemNav), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
我的问题: 我只是想在导航时将 userId 的值作为参数传递给目的地(UserDetails 片段)...但我不想创建 onClickListner 并在包中传递参数。我只想使用导航组件解决方案,因此只需更改在我的导航组件中声明的片段的参数值 我在我的项目中添加了“安全参数”。 我在其中一个目标片段上添加了一个“theUserId”参数:
在mobile_navigation.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/mobile_navigation"
app:startDestination="@+id/dashboardItemNav">
<fragment (...) />
<fragment (...) />
<fragment
android:id="@+id/userDetailItemNav"
android:name="com.example.smart.ui.user.UserFragment"
tools:layout="@layout/fragment_user" >
<argument
android:name="theUserId"
app:argType="long"
android:defaultValue="-1L"
/>
</fragment>
</navigation>
在UserFragment.kt中:
// loading specifics arguments
val argument = arguments?.getLong("theUserId",999L)
Timber.i("userId from MainActivity: $argument")
我试过的:
我在 MainActivity.kt 的 onCreate() 中的 LiveData 观察器是:
viewModel.user.observe(this, Observer { user ->
if (user != null) {
userId = user.id
// TODO: here, change the value of my navigation argument theUserId
}
我试图在我的 LiveData Observer 中添加一个 addOnDestinationChangedListner(但它增加了 Listner)。我也尝试在观察者之后直接放在我的 MainActivity 的 OnCreate 中(似乎更好):
navController.addOnDestinationChangedListener {_, destination, arguments ->
if (destination.id == R.id.userDetailItemNav) {
userId?.let {
val argument = NavArgument.Builder()
.setDefaultValue(it)
.build()
}
}
}
...但是仅在第二次单击 我的 UserDetail 片段的导航项后,userId 值才会更新 。我不明白为什么。
我认为这段代码最好放在我的 Livedata 观察器中:
var userId = 75 // 75 is from my Livedata for example
var myArgs = UserFragmentArgs.Builder().setTheUserId(userId).build()
...但我不知道如何处理 myArgs...如何使用它,如何将它注入导航组件以便下次我单击抽屉项目“Detail User ”,我的参数“theUserId”在片段 UserFragment 中被很好地修改和检索。
感谢您的帮助。
我相信 Documentation 中的示例很容易适用于您的用例。
它不干净,但这是一个有效的解决方案。不幸的是,这个解决方案并没有完全尊重导航组件的精神...
在MainActivity.kt中,在onCreate()函数中:
viewModel.user.observe(this, Observer { user ->
if (user != null) {
userId = user.id
}
}
// (...)
navView.setNavigationItemSelectedListener { menuItem ->
drawerLayout.closeDrawers() // close drawer when item is tapped
val bundle = bundleOf("theUserId" to userId)
when (menuItem.itemId) {
R.id.userDetailItemNav -> {
navController.navigate(menuItem.itemId, bundle)
}
else -> { // for other destination without parameter
navController.navigate(menuItem.itemId)
}
}
true
}
如果您有更好的主意(即能够直接在观察者中更改 UserId 参数的值),我会采纳您的建议很高兴 !.