如果我点击导航控制器中的菜单,如何在两个片段目的地之间传递数据?
how to pass data between two fragments destination If I tap a menu in navigation controller?
-
android
-
android-navigation
-
android-architecture-components
-
android-jetpack
-
android-architecture-navigation
我正在尝试使用导航控制器。我有一个底部导航视图。位于我的 MainActivity 上,它是使用以下代码启动的:
class MainActivity : AppCompatActivity() {
lateinit var navController : NavController
lateinit var logoHeaderImageView : ImageView
var toolbarMenu : Menu? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
logoHeaderImageView = findViewById(R.id.header_lakuin_image_view)
navController = Navigation.findNavController(this,R.id.nav_main_host_fragment)
setupBottomNavMenu(navController)
setupActionBar(navController)
}
fun setupBottomNavMenu(navController: NavController) {
NavigationUI.setupWithNavController(bottom_navigation_view,navController)
}
fun setupActionBar(navController: NavController) {
setSupportActionBar(main_activity_toolbar)
main_activity_toolbar.title = ""
val appBarConfiguration = AppBarConfiguration(
setOf(
// set some destination as the top hierarchy destination, to make the up button doesn't show.
R.id.destination_home,
R.id.destination_order,
R.id.destination_favourite,
R.id.destination_cart,
R.id.destination_profile
))
NavigationUI.setupWithNavController(main_activity_toolbar,navController,appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_toolbar, menu)
toolbarMenu = menu
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
}
这是我的底部导航视图的外观:
所以我想将数据从我的 HomeFragment
(目的地家庭)传递到 OderFragment
(目的地订单)。我通常使用 bundle 或 safeArgs 来传递数据,如下面的代码:
var bundle = bundleOf("amount" to amount)
view.findNavController().navigate(R.id.confirmationAction, bundle)
但我不知道该代码放在哪里,如果我想将数据从我的 HomeFragment
传递到 OderFragment
Post data:
Fragment fragment = new OderFragment();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
fragment.setArguments(bundle);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
Receive data:
Bundle bundle = this.getArguments();
if (bundle != null) {
myInt = bundle.getString("key");
}
就这样:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val bundle = Bundle()
bundle.putString("myname","Hussnain")
return when(item.itemId){
R.id.aboutFragment ->{
navController.navigate(R.id.aboutFragment,bundle)
return true
}else -> {
NavigationUI.onNavDestinationSelected(item,navController) || super.onOptionsItemSelected(item)
}
}
}
导航:
<fragment android:id="@+id/aboutFragment"
android:name="com.cinderellaman.general.ui.fragments
.AboutFragment"
android:label="about_fragment"
tools:layout="@layout/about_fragment">
<argument android:name="myname" app:argType="string"/>
</fragment>
片段:
val args: AboutFragmentArgs by navArgs()
name.text = args.myname
使用 NavigationUI.setupWithNavController(bottom_navigation_view,navController)
时(或者,如果您使用 navigation-ui-ktx
Kotlin 扩展 bottom_navigation_view.setupWithNavController(navController)
),您不能将任何自定义参数传递给目标 - 这是全局导航是他们总是把你带到同一个屏幕同一个状态。
通常,您应该将当前数量之类的数据与导航参数分开保存 - 无论它是在持久化数据库、SharedPreferences 中,还是在进程终止后仍然存在的其他位置,允许用户继续他们正在做的事情即使在重新启动 phone 等
之后
但是,如果您必须为此使用导航参数,您可以提前为目的地设置默认参数(即,每当您的数量发生变化时):
NavDestination orderDestination = navController.graph.findNode(R.id.destination_order)
orderDestination.addArgument("amount", NavArgument.Builder()
.setType(NavType.FloatType)
.setDefaultValue(amount)
.build())
之后,您的 BottomNavigationView
触发 R.id.destination_order
将默认自动包含该参数以及您的新 amount
值。
您可以在片段之间使用共享的 ViewModel:
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}
可在此处找到更多信息:
https://developer.android.com/topic/libraries/architecture/viewmodel#sharing
Call Nav contoller from current fragment. And pass data as a bundle
Ex:
First fragment -
val bundle = Bundle()
bundle.putString("crs",crs); //This is the passing parameter
findNavController().navigate(R.id.action_Classes_to_AddUpdateStudents,bundle)
//Amend your parameter as a second argument
Second fragment -
crs = arguments?.getString("crs").toString()
//Retrieve the data as u usually do with an activiy
android
android-navigation
android-architecture-components
android-jetpack
android-architecture-navigation
我正在尝试使用导航控制器。我有一个底部导航视图。位于我的 MainActivity 上,它是使用以下代码启动的:
class MainActivity : AppCompatActivity() {
lateinit var navController : NavController
lateinit var logoHeaderImageView : ImageView
var toolbarMenu : Menu? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
logoHeaderImageView = findViewById(R.id.header_lakuin_image_view)
navController = Navigation.findNavController(this,R.id.nav_main_host_fragment)
setupBottomNavMenu(navController)
setupActionBar(navController)
}
fun setupBottomNavMenu(navController: NavController) {
NavigationUI.setupWithNavController(bottom_navigation_view,navController)
}
fun setupActionBar(navController: NavController) {
setSupportActionBar(main_activity_toolbar)
main_activity_toolbar.title = ""
val appBarConfiguration = AppBarConfiguration(
setOf(
// set some destination as the top hierarchy destination, to make the up button doesn't show.
R.id.destination_home,
R.id.destination_order,
R.id.destination_favourite,
R.id.destination_cart,
R.id.destination_profile
))
NavigationUI.setupWithNavController(main_activity_toolbar,navController,appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_toolbar, menu)
toolbarMenu = menu
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
}
这是我的底部导航视图的外观:
所以我想将数据从我的 HomeFragment
(目的地家庭)传递到 OderFragment
(目的地订单)。我通常使用 bundle 或 safeArgs 来传递数据,如下面的代码:
var bundle = bundleOf("amount" to amount)
view.findNavController().navigate(R.id.confirmationAction, bundle)
但我不知道该代码放在哪里,如果我想将数据从我的 HomeFragment
传递到 OderFragment
Post data:
Fragment fragment = new OderFragment();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
fragment.setArguments(bundle);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
transaction.commit();
Receive data:
Bundle bundle = this.getArguments();
if (bundle != null) {
myInt = bundle.getString("key");
}
就这样:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val bundle = Bundle()
bundle.putString("myname","Hussnain")
return when(item.itemId){
R.id.aboutFragment ->{
navController.navigate(R.id.aboutFragment,bundle)
return true
}else -> {
NavigationUI.onNavDestinationSelected(item,navController) || super.onOptionsItemSelected(item)
}
}
}
导航:
<fragment android:id="@+id/aboutFragment"
android:name="com.cinderellaman.general.ui.fragments
.AboutFragment"
android:label="about_fragment"
tools:layout="@layout/about_fragment">
<argument android:name="myname" app:argType="string"/>
</fragment>
片段:
val args: AboutFragmentArgs by navArgs()
name.text = args.myname
使用 NavigationUI.setupWithNavController(bottom_navigation_view,navController)
时(或者,如果您使用 navigation-ui-ktx
Kotlin 扩展 bottom_navigation_view.setupWithNavController(navController)
),您不能将任何自定义参数传递给目标 - 这是全局导航是他们总是把你带到同一个屏幕同一个状态。
通常,您应该将当前数量之类的数据与导航参数分开保存 - 无论它是在持久化数据库、SharedPreferences 中,还是在进程终止后仍然存在的其他位置,允许用户继续他们正在做的事情即使在重新启动 phone 等
之后但是,如果您必须为此使用导航参数,您可以提前为目的地设置默认参数(即,每当您的数量发生变化时):
NavDestination orderDestination = navController.graph.findNode(R.id.destination_order)
orderDestination.addArgument("amount", NavArgument.Builder()
.setType(NavType.FloatType)
.setDefaultValue(amount)
.build())
之后,您的 BottomNavigationView
触发 R.id.destination_order
将默认自动包含该参数以及您的新 amount
值。
您可以在片段之间使用共享的 ViewModel:
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}
可在此处找到更多信息:
https://developer.android.com/topic/libraries/architecture/viewmodel#sharing
Call Nav contoller from current fragment. And pass data as a bundle
Ex:
First fragment -
val bundle = Bundle()
bundle.putString("crs",crs); //This is the passing parameter
findNavController().navigate(R.id.action_Classes_to_AddUpdateStudents,bundle)
//Amend your parameter as a second argument
Second fragment -
crs = arguments?.getString("crs").toString()
//Retrieve the data as u usually do with an activiy