Jetpack-navigation基本讲解

秦钟展
2023-12-01

1 配置跳转方式  获取NavController

在 Navigation 里,页面的跳转是交给 NavController 来处理的,获取 NavController 的方法有这么三种:

NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)

2 拿到NavController后,通过 navigate 方法实现跳转

,通过传入 Action 的 id,,比如:  

NavHostFragment
            .findNavController(this)
            .navigate(R.id.action_firstFragment_to_secondFragment)

**action中设置了跳转还可以这样

Navigation.createNavigateOnClickListener(R.id.next_action, null)
<!-- TODO STEP  flow_step_one_dest是另一个fragment id-->
        <action
            android:id="@+id/next_action"
            app:destination="@+id/flow_step_one_dest"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />

3 传参  代码/布局中设置默认值

页面的跳转少不了数据的传递,使用 Navigation,和我们原来的跳转一样,可以通过 Bundle 来传递参数:

val bundle = Bundle()
bundle.putString("name", "SouthernBox")
NavHostFragment
            .findNavController(this)
            .navigate(R.id.action_firstFragment_to_secondFragment, bundle)

如果跳转到 Activity,可以从 intent.extras 获取到 bundle,如果是 Fragment,则从 arguments 获取到。

此外,还可以在 Navigation 的 xml 文件中配置传参,但这种方式目前支持的数据类型比较少,连 boolean 都不支持,而且我还碰到了 bug,所以目前不建议用。

<fragment
        android:id="@+id/flow_step_two_dest"
        android:name="com.example.android.codelabs.navigation.FlowStepFragment"
        tools:layout="@layout/flow_step_two_fragment">

        <argument
            android:name="flowStepNumber"
            app:argType="integer"
            android:defaultValue="2"/>

        <action
            android:id="@+id/next_action"
            app:popUpTo="@id/home_dest">
        </action>
    </fragment>

4 两种切换跳转动画的方式 

<fragment
        android:id="@+id/home_dest"
        android:name="com.example.android.codelabs.navigation.HomeFragment"
        android:label="@string/home"
        tools:layout="@layout/home_fragment">

        <!-- 1 action中添加跳转方式 -->
        <action
            android:id="@+id/next_action"
            app:destination="@+id/flow_step_one_dest"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
        <!-- TODO END STEP 7.1 -->

    </fragment>
button?.setOnClickListener {
            findNavController(it).navigate(R.id.flow_step_one_dest, null)
        }

        //2 TODO - Set NavOptions 方式设置跳转动画
        val options = navOptions {
            anim {
                enter = R.anim.slide_in_right
                exit = R.anim.slide_out_left
                popEnter = R.anim.slide_in_left
                popExit = R.anim.slide_out_right
            }
        }
        view.findViewById<Button>(R.id.navigate_destination_button)?.setOnClickListener {
            findNavController(view).navigate(R.id.flow_step_one_dest, null, options)
        }

5 两种返回方式(代码/xml)

controller.popBackStack()
controller.popBackStack(R.id.detailFragment,true)
<fragment
        android:id="@+id/flow_step_two_dest"
        android:name="com.example.android.codelabs.navigation.FlowStepFragment"
        tools:layout="@layout/flow_step_two_fragment">

        <argument
            android:name="flowStepNumber"
            app:argType="integer"
            android:defaultValue="2"/>
        <!-- 1 action 回退位置,栈里没有不执行 -->
        <action
            android:id="@+id/next_action"
            app:popUpTo="@id/home_dest">
        </action>
    </fragment>

 类似资料: