Navigation Architecture Componen

2019-01-03  本文已影响32人  为什么要简称

6.更换导航过度效果

每个navigat()都有个不怎么滴的过渡效果,behold:


1.gif

默认的转换效果,和其他与调用相关的属性都可以override。can be overridden by including a set of NavOptions. NavOptions uses a Builder pattern which allows you to override and set only the options you need. There's also a ktx DSL for NavOptions, which is what you'll be using.
现在先定义一些动画给转换效果:

image.png
添加自定义效果到Transition中

1.打开HomeFragment
2.定义NavOptions,传入navigate()中

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().navigate(R.id.flow_step_one_dest, null, options)
}

3.step 5的东西就不用再保留了
4.运行一下试试看

7.Navigate using actions

导航系统可以通过action进行导航,在导航图中的线条代表着action。


image.png

用action导航比用destination导航多了这么些好处:

下面的图展示一个连接了flow_step_one_destflow_step_two_dest的action

image.png
<fragment
    android:id="@+id/flow_step_one_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment">

    <argument
        .../>

    <action
        android:id="@+id/next_action"
        app:destination="@+id/flow_step_two_dest">
    </action>
</fragment>

<fragment
    android:id="@+id/flow_step_two_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment">
    <!-- ...removed for simplicity-->
</fragment>

behold:

再看一个


image.png
<fragment
    android:id="@+id/home_dest"
    android:name="com.example.android.codelabs.navigation.HomeFragment"
.../>

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

    <argument
        .../>

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

notice:

使用action进行导航

1.打开mobile_navigation.xml
2.在design模式从home_dest拖一条线线到flow_step_one_dest

image.png
3.搞action,添加或修改属性:
 view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
    Navigation.createNavigateOnClickListener(R.id.next_action, null)
)

6.跑一跑

8.使用safe args

Safe Args

navigation组件有一个Gradle插件,名唤safe args,that generates simple object and builder classes for type-safe access to arguments specified for destinations and actions.

Safe args可以让我们在destination之间传递数据时这样搞代码:

val username = arguments?.getString("usernameKey")

使用生成的getter和setter替代上面:

val username = args.username

因为这是类型安全的, 使用safe args生成类是用action进行导航并且在导航时传递arguments的最佳办法。

使用safe args传递值

1.打开app/build.gradle注意应用插件

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'androidx.navigation.safeargs'

android { 
   //...
}

2.打开mobile_navigation.xml,注意flow_step_one_dest中的arguments是怎么定义的

<fragment
android:id="@+id/flow_step_one_dest"
android:name="com.example.android.codelabs.navigation.FlowStepFragment"
tools:layout="@layout/flow_step_one_fragment">
<argument
    android:name="flowStepNumber"
    app:argType="integer"
    android:defaultValue="1"/>

<action...>
</action>
</fragment>

通过<argment>,safe args生成了一个唤做FlowStepFragmentArgs的类

image.png

<argment>中通过android:name="flowStepNumber"定义了一个叫做"flowStepNumber"的argment,所以在生成类FlowStepFragmentArgs中也有一个叫做flowStepNumber的变量,并且还有getter和setter。
3.打开FlowStepFragment
4.注释掉以下代码

// Comment out this line
// val flowStepNumber = arguments?.getInt("flowStepNumber")

因为这是老式代码,并非类型安全的代码,我们来用safe args撸
5.通过FlowStepFragmentArgs改造代码,以类型安全的方式获取FlowStepFragment的参数。

val safeArgs = FlowStepFragmentArgs.fromBundle(arguments)
val flowStepNumber = safeArgs.flowStepNumber
Safe Args Direction classes

我们也可以通过safe args用类型安全的方式来导航,参数自选。
这时我们会用到生成的Direction类。

image.png
每一个包含action的destination都会生成Direction类,类里包含了为destination中每个action提供的方法。
举个栗子,navigate_action_button点击监听可以变成这个样子:
// Note the usage of curly braces since we are defining the click listener lambda
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener{
    val action = HomeFragmentDirections.nextAction()
    action.setFlowStepNumber(1)
    findNavController().navigate(action)
}
上一篇下一篇

猜你喜欢

热点阅读