繁体   English   中英

导航组件参数默认值

[英]Navigation component arguments default value

在导航组件中,当从第一个片段向第二个片段发送参数时,默认值不会从导航图中获取。

这是我的代码:

导航图.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/navigation_graph"
    app:startDestination="@id/firstFragment">


    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.navigationcomponent.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first" >
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment"
            app:enterAnim="@anim/nav_default_enter_anim" />

        <argument
            android:name="clickFrom"
            app:argType="string"
            android:defaultValue="From First Fragment" />
        <argument
            android:name="clickFragmentPosition"
            app:argType="integer"
            android:defaultValue="1" />

    </fragment>

    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.navigationcomponent.SecondFragment"
        android:label="fragment_second"
        tools:layout="@layout/fragment_second" />


</navigation>

第一个片段:

class FirstFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val bundle = Bundle()
        bundle.putBoolean("IsFirstFragment", true)
        val navController = Navigation.findNavController(activity!!, R.id.my_nav_host_fragment)

        btnNext.setOnClickListener {
            navController.navigate(R.id.action_firstFragment_to_secondFragment, bundle)
        }
    }
}

第二个片段:

class SecondFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val isFromFirstFragment = arguments?.getBoolean("IsFirstFragment", false)
        Log.d(TAG, "$isFromFirstFragment")
        Log.d(TAG, "${FirstFragmentArgs.fromBundle(arguments!!).clickFrom} ${FirstFragmentArgs.fromBundle(arguments!!).clickFragmentPosition}")

        val navController = Navigation.findNavController(activity!!, R.id.my_nav_host_fragment)
        btnBack.setOnClickListener {
            navController.navigateUp()
        }

        navController.addOnDestinationChangedListener { controller, destination, arguments ->
            Log.d("TAG", "${destination.label}");
        }
    }

    companion object {
        private const val TAG: String = "SecondFragment"
    }
}

在这里,在第二个片段中获取默认值时,我收到空指针异常

Log.d(TAG, "${FirstFragmentArgs.fromBundle(arguments!!).clickFrom} ${FirstFragmentArgs.fromBundle(arguments!!).clickFragmentPosition}")

我的问题是,如何获取使用navigation_graph.xml设置的参数值? 当您重新构建项目时,导航图具有自动生成的 getter。 是否有任何架构可以使用默认值绑定自动生成的 setter?

如果要将参数从FirstFragment发送到SecondFragment ,则应将navigation_graph.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/navigation_graph"
    app:startDestination="@id/firstFragment">


    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.navigationcomponent.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first" >
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment"
            app:enterAnim="@anim/nav_default_enter_anim" />

    </fragment>

    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.navigationcomponent.SecondFragment"
        android:label="fragment_second"
        tools:layout="@layout/fragment_second">

        <argument
            android:name="clickFrom"
            app:argType="string"
            android:defaultValue="From First Fragment" />

        <argument
            android:name="clickFragmentPosition"
            app:argType="integer"
            android:defaultValue="1" />

        <argument
            android:name="isFirstFragment"
            app:argType="boolean"
            android:defaultValue="false" />

    </fragment>


</navigation>

然后,您可以像这样从FirstFragment传递参数:

class FirstFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val navController = Navigation.findNavController(activity!!, R.id.my_nav_host_fragment)

        btnNext.setOnClickListener {
            navController.navigate(
                FirstFragmentDirections.actionFirstFragmentToSecondFragment( // this is an auto-generated class & method
                    // specify your arguments here: For example:
                    isFirstFragment = true,
                    clickFrom = "your argument here",
                    clickFragmentPosition = 1
                    // for default values, you can leave this blank
                )
            )
        }
    }
}

然后在SecondFragment 中检索参数

class SecondFragment : Fragment() {

    private val arguments: SecondFragmentArgs by navArgs() // add this line to retrieve arguments from navigation

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val isFromFirstFragment = arguments.isFirstFragment
        Log.d(TAG, "$isFromFirstFragment")
        Log.d(TAG, "${arguments.clickFrom} ${arguments.clickFragmentPosition}")

        val navController = Navigation.findNavController(activity!!, R.id.my_nav_host_fragment)
        btnBack.setOnClickListener {
            navController.navigateUp()
        }

        navController.addOnDestinationChangedListener { controller, destination, arguments ->
            Log.d("TAG", "${destination.label}");
        }
    }

    companion object {
        private const val TAG: String = "SecondFragment"
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM