在 Navigation 里,页面的跳转是交给 NavController 来处理的,获取 NavController 的方法有这么三种:
NavHostFragment.findNavController(Fragment)
Navigation.findNavController(Activity, @IdRes int viewId)
Navigation.findNavController(View)
,通过传入 Action 的 id,,比如:
NavHostFragment
.findNavController(this)
.navigate(R.id.action_firstFragment_to_secondFragment)
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" />
页面的跳转少不了数据的传递,使用 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>
<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)
}
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>