Jetpack 实战系列(一) | 写Java版的sunflower 分析Java版本

最近在研究Jetpack,这是我看见的一个比较好的系列文,这里分享给大家,希望对大家的学习和工作有所帮助。
原文地址:https://www.jianshu.com/p/9bd73edeb233

我们用的是标准jetpack套件,所以我们采用DataBinding,并且,项目结构是一个抽屉布局和主页面

Navigation的主要元素

Navigation的主要元素有如下三个:

  1. Navigation Graph。一种xml资源文件,里面包含需要统一管理的所有页面以及页面之间的关系。
  2. NavHostFragment。一种特殊的Fragment,是其他Fragment的容器,在Navigation Graph中的Fragment是通过NavHostFragment进行展示的。
  3. NavController。用于在代码中完成Navigation Graph中具体的页面切换工作。

上述三者关系为:在切换Fragment时,使用NavController对象,告知其要去Navigation Graph中的哪个Fragment;NavController会将这个Fragment展示在NavHostFragment中。

用Navigation创建UI

  1. 在res文件夹下创建navigation目录,然后在这个新建的navigation目录下创建一个Navigation Resource File文件

File name设为nav_graph,Root element用默认的navigation。生成之后Android Studio会询问是否自动添加相关依赖,单击OK,等待依赖添加完成。

  1. NavHostFragment是一种特殊的Fragment,所以需要将其添加到其依托的Activity布局文件中。在NavHostFragment依托的Activity布局文件下。
    DataBinding+DrawLayout+NavHostFragment+NavigationView
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <!-- 侧滑 -->
    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <!--
                标题栏:配合Toolbar有收缩和扩展的效果
            -->
            <com.google.android.material.appbar.AppBarLayout
                android:id="@+id/appbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/AppTheme.AppBarOverlay">

                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

            </com.google.android.material.appbar.AppBarLayout>
            <fragment
                android:id="@+id/garden_nav_fragment"
android:name="androidx.navigation.fragment.NavHostFragmen"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_graph"
                />

        </LinearLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navigation_view"
            style="@style/Widget.MaterialComponents.NavigationView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/menu_navigation" />
    </androidx.drawerlayout.widget.DrawerLayout>
</layout>

需要注意的是android:name属性为固定写法,告知系统这是一个特殊的Fragment;app:defaultNavHost设置为true,此时当用户按下返回键时,系统自动将当前所展示的Fragment退出;app:navGraph属性用来设置这个Fragment对应的导航图。

回到nav_graph导航图上,可以看到上面设置的NavHostFragment

  1. 创建destination。这个部分有点像Xcode的StoryBoard,可以利用可视化的方式直观展示页面关系。

(这里也可以利用代码直接关联已有的页面),可以是Fragment,也可以是Activity,但是Fragment更为常见。我们代码结构创建一个Activity,剩下全是Fragment结构

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

    <fragment
        android:id="@+id/gardenFragment"
        android:name="top.zcwfeng.sunflower_java.GardenFragment"
        android:label="fragment_garden"
        tools:layout="@layout/fragment_garden" >
        <action
            android:id="@+id/action_gardenFragment_to_planDetail"
            app:destination="@id/planDetail" />
    </fragment>
......

navigation标签下多了一个app:startDestination属性,这个属性指定了起始的destination

  1. 实现Fragment页面的切换。使用上面的方法创建一个PlanDetailFragment,然后回到nav_graph导航图。

用鼠标选中gardenFragment,拖动右面的小圆圈,使其指向planDetailFragment

查看源码,可以看到多了一个action标签。里面有个app:destination属性,表明其目的地是PlanDetailFragment

添加页面切换动画效果

和普通的写法一样,这里也同样支持添加切换页面的动画效果。
在res/anim目录下加入动画文件

slide_in_left:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="-100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide"/>
</set>
-----------------
slide_in_right:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide"/>
</set>
-----------------
slide_out_left:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0%" android:toXDelta="-100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide"/>
</set>
-----------------
slide_out_right:
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0%" android:toXDelta="100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="@integer/slide"/>
</set>

之后,回到nav_graph导航图,在Design面板中设置动画文件。

<navigation ...>

    <fragment
        android:id="@+id/gardenFragment"
        ...>
        <action
            android:id="@+id/action_gardenFragment_to_planDetail"
            app:destination="@id/planDetail"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_in_right" />
    </fragment>
    <fragment
        android:id="@+id/planDetail"
        ...
</navigation>

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

我把自己这段时间整理的Android最重要最热门的学习方向资料放在了我们2000人的技术交流圈共享文件夹中(点击此处可加入),里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。

群资源共享(文件密码找管理雨墨),欢迎大家一起学习和探讨。

猜你喜欢

转载自blog.csdn.net/m0_46962786/article/details/114456462