【Android】Navigation初试-官方demo分析

在这里插入图片描述
从官方整了个demo下来,全部kotlin编写,对我这种基本从未用过kotlin的老年选手来说理解真是难搞。

MainActivity

首先按照官方步骤,从MainActivity里走起。
先看布局。一眼就能看到这玩意。

<fragment
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/my_nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            app:navGraph="@navigation/mobile_navigation"
            app:defaultNavHost="true"
        />

android:name=“androidx.navigation.fragment.NavHostFragment” and app:defaultNavHost=“true” connect the system back button to the NavHostFragment
app:navGraph="@navigation/mobile_navigation" associates the NavHostFragment with a navigation graph. This navigation graph specifies all the destinations the user can navigate to, in this NavHostFragment.

官方说明: app:defaultNavHost=true和name=NavHostFragment将返回键接给了NavHostFragment,意思应该就是这样设置之后返回键可以用于fragment回退切换而不是bang掉了activity。
下一句也没什么好说的,连上了一个graph。graph是这套逻辑的核心。

然后进代码块。官方这个demo从界面上看就知道很简单,只包含几个点击事件的处理,所以关注的逻辑基本只有点击事件就够了。

Finally, when a user does something like clicking a button, you need to trigger a navigate command. A special class called the NavController is what triggers the fragment swaps in the NavHostFragment.

来看看官方关于点击事件的说明。
当用户执行诸如单击按钮之类的操作时,需要触发导航命令。一个名为NavController的特殊类触发了NavHostFragment中的片段交换。

		val host: NavHostFragment = supportFragmentManager
                .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return

        // Set up Action Bar
        val navController = host.navController

        navController.addOnNavigatedListener { _, destination ->
            val dest: String = try {
                resources.getResourceName(destination.id)
            } catch (e: Resources.NotFoundException) {
                Integer.toString(destination.id)
            }

            Toast.makeText(this@MainActivity, "Navigated to $dest",
                    Toast.LENGTH_SHORT).show()
            Log.d("NavigationActivity", "Navigated to $dest")
        }

学没学过kotlin不是重点,只要理解中心思想:给你的NavHostFragment对象创建一个Controller→用这个Controller控制。

甚至可以给加载在这个navgraph上的每一次跳转做统一事件。统一监听nb,一瞬间想到了多种玩法。
在这里插入图片描述

Navigation指定初始碎片

接着开始进入graph一探究竟

<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"
    app:startDestination="@+id/home_dest">

app:startDestination="@+id/home_dest" 指定了起始碎片,顺着id找fragment↓

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

没什么好说的,进HomeFragment看看吧。

Fragment两种事件监听方法

		//TODO STEP 5 - Set an OnClickListener, using Navigation.createNavigateOnClickListener()
		val button = view.findViewById<Button>(R.id.navigate_destination_button)
        button?.setOnClickListener {
            findNavController().navigate(R.id.flow_step_one_dest)
        }
        //TODO STEP 7.2 - Update the OnClickListener to navigate using an action
        view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
                Navigation.createNavigateOnClickListener(R.id.next_action, null)
        )

直奔跳转事件,上面涉及到了两种事件触发方法。分别是使用controller控制,和直接绑定actionid
此处的所有id都是指graph里的东西,别傻到去布局文件里找啊。

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

        
        <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" />
        

    fragment>
	  

特意写了个注释。防止未来忘了。在这里插入图片描述
老年人伤不起。

The popUpTo attribute is used - this action will pop fragments off of the back-stack until you reach home_dest

清栈就用popUpTo跳完事。

Fragment两种切换动画设置方法

The default transition, as well as other attributes associated with the call, 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.

官方说明。第一眼是不是有人会看不懂,看不懂也不要紧。首先知道这玩意能做动画切换就行了。
【Android】Navigation初试-官方demo分析_第1张图片

第一种跳转动画方法

		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)
        }

动画怎么写就先不提了。

第二种跳转动画方法

之前第二种点击事件应该有人已经注意到了。

 <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" />

在这里插入图片描述谷歌的逻辑真是做的越来越简单清楚nb了。人人可编程指日可待。有种快要被淘汰的危机感。

布局属性配置

     <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
                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"
        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>

这是其中两个碎片布置。argument中的区别只有,defaultValue。
然后去指定的FlowStepFragment里找。

 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
        setHasOptionsMenu(true)
        val flowStepNumber = arguments?.getInt("flowStepNumber")
        return when (flowStepNumber) {
            2 -> inflater.inflate(R.layout.flow_step_two_fragment, container, false)
            else -> inflater.inflate(R.layout.flow_step_one_fragment, container, false)
        }
    }

2填充two,其他填充one。没啥好说的
菜单和deeplink目前项目没需求就暂且不提。
写demo去再慢慢看源码原理。

你可能感兴趣的:(Android)