Android导航组件:在片段中传递值(参数)

时间:2019-12-23 08:35:26

标签: android android-fragments android-architecture-navigation

我做了什么:

我创建了导航抽屉活动,作为导航抽屉活动的新格式,根据新的Android架构,我使用 [导航组件] [ 1] 结构。

下面的Auth error from APNS or Web Push ServiceNavigationView的{​​{1}}代码是当我单击任何导航项时的打开片段。

NavController

这是针对NavigationUI的:

    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    mAppBarConfiguration = new AppBarConfiguration.Builder(
            R.id.nav_home, R.id.nav_profile, R.id.nav_privacy_policy,
            R.id.nav_terms, R.id.nav_contact_us, R.id.nav_share, R.id.nav_send)
            .setDrawerLayout(drawer)
            .build();
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);

正在使用此nav_host_fragment

进行导航
<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:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

我想做什么:

现在,我想在Fragment调用时将某些值作为bundle(参数)传递给Fragment。

场景:我有两个片段navigation/mobile_navigation.xml<?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/mobile_navigation" app:startDestination="@+id/nav_home"> <fragment android:id="@+id/nav_home" android:name="com.sohamerp.marsremedies.fragment.HomeFragment" android:label="@string/menu_home" tools:layout="@layout/fragment_home" /> <fragment android:id="@+id/nav_profile" android:name="com.sohamerp.marsremedies.fragment.ProfileFragment" android:label="@string/menu_my_profile" tools:layout="@layout/fragment_profile" /> <fragment android:id="@+id/nav_privacy_policy" android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment" android:label="@string/menu_privacy_policy" tools:layout="@layout/fragment_privacy_policy" /> <fragment android:id="@+id/nav_terms" android:name="com.sohamerp.marsremedies.fragment.TermsConditionFragment" android:label="@string/menu_terms" tools:layout="@layout/fragment_terms_condition" /> <fragment android:id="@+id/nav_contact_us" android:name="com.sohamerp.marsremedies.fragment.ContactUsFragment" android:label="@string/menu_contact_us" tools:layout="@layout/fragment_terms_condition" /> </navigation> ,在两个片段中,我只是相应地打开WebView内的链接。因此,当我单击PrivacyPolicyFragment的菜单项时,我将传递与之相关的链接。

在这种TermsConditionsFragment新结构中,打开片段,如何传递参数?

有帮助吗?

5 个答案:

答案 0 :(得分:2)

要将参数传递给其他分片/目的地,请使用Safe Args,以确保类型安全。就像@bromden所示,安全Args会为action起源的每个片段/目标生成一个类。然后,您可以将参数传递到导航到片段的action中。

在接收片段中,如果您的代码在Kotlin中,请说PrivacyFragment,由navArgs()属性委托使用以访问参数。即

val args: PrivacyFragmentArgs by navArgs()

要更好地理解这一点,请访问Pass data between destinations

答案 1 :(得分:2)

所以我忘了通过以下链接:Define Destination Arguments

但是这个答案对像我这样的所有懒惰人很有帮助:

在项目级别 build.gradle 中添加依赖项:

classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0"

在应用程序级别 build.gradle 中应用插件:

apply plugin: "androidx.navigation.safeargs"

使用XML:预定义(静态)值:

在导航 /navigation/mobile_navigation.xml 的xml文件中,如下声明argument标记,也可以通过this link设计:

<fragment
    android:id="@+id/nav_privacy_policy"
    android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment"
    android:label="@string/menu_privacy_policy"
    tools:layout="@layout/fragment_privacy_policy" >
    <argument
        android:name="privacyPolicyLink"
        app:argType="string"
        android:defaultValue="http://sohamerp.com/avo/avo_privacy_policy.html"/>
</fragment>

<fragment
    android:id="@+id/nav_terms"
    android:name="com.sohamerp.marsremedies.fragment.PrivacyPolicyFragment"
    android:label="@string/menu_terms"
    tools:layout="@layout/fragment_terms_condition" >
    <argument
        android:name="privacyPolicyLink"
        app:argType="string"
        android:defaultValue="http://sohamerp.com/avo/avo_privacy_policy.html"/>
</fragment>

现在您必须像这样在Fragment中编写代码:

if(getArguments() != null) {
    // The getPrivacyPolicyLink() method will be created automatically.
    String url = PrivacyPolicyFragmentArgs.fromBundle(getArguments()).getPrivacyPolicyLink();
}

希望对您有帮助。

答案 2 :(得分:1)

您可以实现NavigationView.OnNavigationItemSelectedListener 并执行以下操作:

 override fun onNavigationItemSelected(item: MenuItem): Boolean {
   drawer_layout.closeDrawers()

        if (item.itemId == nv_navigation_drawer_navigation_view.checkedItem?.itemId)
            return false

     Handler().postDelayed({
                when (item.itemId) {
                    R.id.nav_privacy_policy -> {
                           val action = FragmentDirections.actionFragmentToPrivacyFragment("Policy link")

                     findNavController().navigate(action)

                    }
                }
            }, DRAWER_NAVIGATION_DELAY)
  return true
    }

在xml中,您可以在正在接收的片段中添加参数

   <fragment
    android:id="@+id/nav_privacy_policy"
    android:name=".fragment.PrivacyPolicyFragment"
    android:label="@string/menu_privacy_policy"
    tools:layout="@layout/fragment_privacy_policy">

    <argument
        android:name="policy"
        app:argType="string" />
</fragment>

答案 3 :(得分:0)

您还可以传递可序列化的对象,枚举值和原始类型的数组。 例如:

new Example(); new Example()

然后,将参数添加到xml

enum class ObjectType : Serializable {
    FIRST, SECOND
}

注意,您应该指定完整路径!

答案 4 :(得分:0)

在这种情况下,您可以使用

  private NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
  // Create the Bundle to pass, you can put String, Integer, or serializable object
  Bundle bundle = new Bundle();
  bundle.putString("link","http://yourlink.com/policy");
  bundle.putSerializable("USER", user); // Serializable Object
  navController.navigate(R.id.nav_terms, bundle); // called fragment with agruments

如有任何帮助,您可以回复它