百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

Android Jetpack从入门到精通(深度好文,值得收藏)

yuyutoo 2024-10-12 01:29 12 浏览 0 评论

阅读前请点击右上角“关注”,每天免费获取Android知识解析及面试解答。Android架构解析,只做职场干货,完全免费分享!

前言

即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇。

记得去年第一次参加谷歌开发者大会的时候,就被Navigation的图形导航界面给迷住了,一句卧槽就代表了小王的全部心情~,我们可以看一下来自网络的一张图片:

所以,Android Jetpack学习之旅就开始了。

本人打算每周学习一个组件(上图的左上区域),最后将所学的组件组成一个简单的Demo。同时,刚刚过去的2019年谷歌开发者大会宣布亲儿子Kotlin成为开发Android的首选语言,所以本文的Demo也将都会采用Kotlin编写。

本章结束后登录部分完成效果:

语言:KotlinDemo地址:https://github.com/mCyp/Hoo

目录

一、简介

1. 定义

Navigation是什么呢?谷歌的介绍视频上说:

Navigation是一个可简化Android导航的库和插件

更确切的来说,Navigation是用来管理Fragment的切换,并且可以通过可视化的方式,看见App的交互流程。这完美的契合了Jake Wharton大神单Activity的建议。

2. 优点

  • 处理Fragment的切换(上文已说过)
  • 默认情况下正确处理Fragment的前进和后退
  • 为过渡和动画提供标准化的资源
  • 实现和处理深层连接
  • 可以绑定Toolbar、BottomNavigationView和ActionBar等
  • SafeArgs(Gradle插件) 数据传递时提供类型安全性
  • ViewModel支持

3. 准备

如果想要进行下面的学习,你需要 3.2 或者更高的Android studio。

4. 学习方式

最好的学习方式仍然是通过官方文档,下面是官方的学习地址:谷歌官方教程:Navigation Codelab谷歌官方文档:Navigation官方Demo:Demo地址

二、实战

在实战之前,我们先来了解一下Navigation中最关键的三要素,他们是:

名词解释Navigation Graph(New XML resource)如我们的第一张图所示,这是一个新的资源文件,用户在可视化界面可以看出他能够到达的Destination(用户能够到达的屏幕界面),以及流程关系。NavHostFragment(Layout XML view)当前Fragment的容器NavController(Kotlin/Java object)导航的控制者

可能我这么解释还是有点抽象,做一个不是那么恰当的比喻,我们可以将Navigation Graph看作一个地图,NavHostFragment看作一个车,以及把NavController看作车中的方向盘,Navigation Graph中可以看出各个地点(Destination)和通往各个地点的路径,NavHostFragment可以到达地图中的各个目的地,但是决定到什么目的地还是方向盘NavController,虽然它取决于开车人(用户)。

第一步 添加依赖

模块层的build.gradle文件需要添加:

ext.navigationVersion = "2.0.0"
dependencies {
    //... 
    implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.navigationVersion"
    implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
}

如果你要使用SafeArgs插件,还要在项目目录下的build.gradle文件添加:

buildscript {
    ext.navigationVersion = "2.0.0"
    dependencies {
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
    }
}

以及模块下面的build.gradle文件添加:

apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'

第二步 创建navigation导航

  1. 创建基础目录:资源文件res目录下创建navigation目录 -> 右击navigation目录New一个Navigation resource file
  2. 创建一个Destination,如果说navigation是我们的导航工具,Destination是我们的目的地,在此之前,我已经写好了一个WelcomeFragment、LoginFragment和RegisterFragment,添加Destination的操作完成后如下所示:

除了可视化界面之外,我们仍然有必要看一下里面的内容组成,login_navigation.xml:

<navigation
    ...
    android:id="@+id/login_navigation"
    app:startDestination="@id/welcome">

    <fragment
        android:id="@+id/login"
        android:name="com.joe.jetpackdemo.ui.fragment.login.LoginFragment"
        android:label="LoginFragment"
        tools:layout="@layout/fragment_login"
        />

    <fragment
        android:id="@+id/welcome"
        android:name="com.joe.jetpackdemo.ui.fragment.login.WelcomeFragment"
        android:label="LoginFragment"
        tools:layout="@layout/fragment_welcome">
        <action
            .../>
        <action
            .../>
    </fragment>

    <fragment
        android:id="@+id/register"
        android:name="com.joe.jetpackdemo.ui.fragment.login.RegisterFragment"
        android:label="LoginFragment"
        tools:layout="@layout/fragment_register"
        >

        <argument
            .../>
    </fragment>
</navigation>

我在这里省略了一些不必要的代码。让我们看一下navigation标签的属性:

属性解释app:startDestination默认的起始位置

第三步 建立NavHostFragment

我们创建一个新的LoginActivity,在activity_login.xml文件中:

<androidx.constraintlayout.widget.ConstraintLayout
    ...>

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

</androidx.constraintlayout.widget.ConstraintLayout>

有几个属性需要解释一下:

属性解释android:name值必须是androidx.navigation.fragment.NavHostFragment,声明这是一个NavHostFragmentapp:navGraph存放的是第二步建好导航的资源文件,也就是确定了Navigation Graphapp:defaultNavHost="true"与系统的返回按钮相关联

第四步 界面跳转、参数传递和动画

在WelcomeFragment中,点击登录和注册按钮可以分别跳转到LoginFragment和RegisterFragment中。

image

这里我使用了两种方式实现:

方式一 利用ID导航

目标:WelcomeFragment携带key为name的数据跳转到LoginFragment,LoginFragment接收后显示。Have a account ? Login按钮的点击事件如下:

btnLogin.setOnClickListener {
            // 设置动画参数
            val navOption = 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
                }
            }
            // 参数设置
            val bundle = Bundle()
            bundle.putString("name","TeaOf")
            findNavController().navigate(R.id.login, bundle,navOption)
}

后续LoginFragment的接收代码比较简单,直接获取Fragment中的Bundle即可,这里不再出示代码。最后的效果:

方式二 利用Safe Args

目标:WelcomeFragment通过Safe Args将数据传到RegisterFragment,RegisterFragment接收后显示。再看一下已经展示过的login_navigation.xml:

<navigation
    ...>

    <fragment
        ...
        />

    <fragment
        android:id="@+id/welcome"
        >
        <action
            android:id="@+id/action_welcome_to_login"
            app:destination="@id/login"/>
        <action
            android:id="@+id/action_welcome_to_register"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"
            app:destination="@id/register"/>
    </fragment>

    <fragment
        android:id="@+id/register"
        ...
        >

        <argument
            android:name="EMAIL"
            android:defaultValue="2005@qq.com"
            app:argType="string"/>
    </fragment>
</navigation>

细心的同学可能已经观察到navigation目录下的login_navigation.xml资源文件中的action标签和argument标签,这里需要解释一下:action标签

属性作用app:destination跳转完成到达的fragment的Idapp:popUpTo将fragment从栈中弹出,直到某个Id的fragment

argument标签

属性作用android:name标签名字app:argType标签的类型android:defaultValue默认值

点击Android studio中的Make Project按钮,可以发现系统为我们生成了两个类:

WelcomeFragment中的JOIN US按钮点击事件:

btnRegister.setOnClickListener {
            val action = WelcomeFragmentDirections
                .actionWelcomeToRegister()
                .setEMAIL("TeaOf1995@Gamil.com")
            findNavController().navigate(action)
}

RegisterFragment中的接收:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // ...
        val safeArgs:RegisterFragmentArgs by navArgs()
        val email = safeArgs.email
        mEmailEt.setText(email)
}

以及效果:

需要提及的是,如果不用Safe Args,action可以由Navigation.createNavigateOnClickListener(R.id.next_action, null)方式生成,感兴趣的同学可以自行编写。

三、更多

Navigation可以绑定menus、drawers和bottom navigation,这里我们以bottom navigation为例,我先在navigation目录下新创建了main_navigation.xml,接着新建了MainActivity,下面则是activity_main.xml:

<LinearLayout
    ...>

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

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/navigation_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        app:itemIconTint="@color/colorAccent"
        app:itemTextColor="@color/colorPrimary"
        app:menu="@menu/menu_main"/>

</LinearLayout>

MainActivity中的处理也十分简单:

class MainActivity : AppCompatActivity() {

    lateinit var bottomNavigationView: BottomNavigationView

    override fun onCreate(savedInstanceState: Bundle?) {
        //...
        val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
        val navController = host.navController
        initWidget()
        initBottomNavigationView(bottomNavigationView,navController)
    }

    private fun initBottomNavigationView(bottomNavigationView: BottomNavigationView, navController: NavController) {
        bottomNavigationView.setupWithNavController(navController)
    }

    private fun initWidget() {
        bottomNavigationView = findViewById(R.id.navigation_view)
    }
}

效果:

四、总结

上图概括了本文的一些知识点,当然还有一些知识点没有涉及,比如深层连接等,其次,本文只是一篇入门型博客,关于更深层次的学习,本人会逐步进行。本人水平有限,文章难免有误,欢迎指正。Over~

参考文章:

谷歌实验室Android官方架构组件Navigation:大巧不工的Fragment管理框架

相关推荐

Mysql和Oracle实现序列自增(oracle创建序列的sql)

Mysql和Oracle实现序列自增/*ORACLE设置自增序列oracle本身不支持如mysql的AUTO_INCREMENT自增方式,我们可以用序列加触发器的形式实现,假如有一个表T_WORKM...

关于Oracle数据库12c 新特性总结(oracle数据库19c与12c)

概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...

MySQL CREATE TABLE 简单设计模板交流

推荐用MySQL8.0(2018/4/19发布,开发者说同比5.7快2倍)或同类型以上版本....

mysql学习9:创建数据库(mysql5.5创建数据库)

前言:我也是在学习过程中,不对的地方请谅解showdatabases;#查看数据库表createdatabasename...

MySQL面试题-CREATE TABLE AS 与CREATE TABLE LIKE的区别

执行"CREATETABLE新表ASSELECT*FROM原表;"后,新表与原表的字段一致,但主键、索引不会复制到新表,会把原表的表记录复制到新表。...

Nike Dunk High Volt 和 Bright Spruce 预计将于 12 月推出

在街上看到的PandaDunk的超载可能让一些球鞋迷们望而却步,但Dunk的浪潮仍然强劲,看不到尽头。我们看到的很多版本都是为女性和儿童制作的,这种新配色为后者引入了一种令人耳目一新的新选择,而...

美国多功能舰载雷达及美国海军舰载多功能雷达系统技术介绍

多功能雷达AN/SPY-1的特性和技术能力,该雷达已经在美国海军服役了30多年,其修改-AN/SPY-1A、AN/SPY-1B(V)、AN/SPY-1D、AN/SPY-1D(V),以及雷神...

汽车音响怎么玩,安装技术知识(汽车音响怎么玩,安装技术知识视频)

全面分析汽车音响使用或安装技术常识一:主机是大多数人最熟习的音响器材,有关主机的各种性能及规格,也是耳熟能详的事,以下是一些在使用或安装时,比较需要注意的事项:LOUDNESS:几年前的主机,此按...

【推荐】ProAc Response系列扬声器逐个看

有考牌(公认好声音)扬声器之称ProAcTablette小音箱,相信不少音响发烧友都曾经,或者现在依然持有,正当大家逐渐掌握Tablette的摆位设定与器材配搭之后,下一步就会考虑升级至表现更全...

#本站首晒# 漂洋过海来看你 — BLACK&amp;DECKER 百得 BDH2000L无绳吸尘器 开箱

作者:初吻给了烟sco混迹张大妈时日不短了,手没少剁。家里有了汪星人,吸尘器使用频率相当高,偶尔零星打扫用卧式的实在麻烦(汪星人:你这分明是找借口,我掉毛是满屋子都有,铲屎君都是用卧式满屋子吸的,你...

专题|一个品牌一件产品(英国篇)之Quested(罗杰之声)

Quested(罗杰之声)代表产品:Q212FS品牌介绍Quested(罗杰之声)是录音监听领域的传奇品牌,由英国录音师RogerQuested于1985年创立。在成立Quested之前,Roger...

常用半导体中英对照表(建议收藏)(半导体英文术语)

作为一个源自国外的技术,半导体产业涉及许多英文术语。加之从业者很多都有海外经历或习惯于用英文表达相关技术和工艺节点,这就导致许多英文术语翻译成中文后,仍有不少人照应不上或不知如何翻译。为此,我们整理了...

Fyne Audio F502SP 2.5音路低音反射式落地音箱评测

FyneAudio的F500系列,有新成员了!不过,新成员不是新的款式,却是根据原有款式提出特别版。特别版产品在原有型号后标注了SP字样,意思是SpecialProduction。Fyne一共推出...

有哪些免费的内存数据库(In-Memory Database)

以下是一些常见的免费的内存数据库:1.Redis:Redis是一个开源的内存数据库,它支持多种数据结构,如字符串、哈希表、列表、集合和有序集合。Redis提供了快速的读写操作,并且支持持久化数据到磁...

RazorSQL Mac版(SQL数据库查询工具)

RazorSQLMac特别版是一款看似简单实则功能非常出色的SQL数据库查询、编辑、浏览和管理工具。RazorSQLformac特别版可以帮你管理多个数据库,支持主流的30多种数据库,包括Ca...

取消回复欢迎 发表评论: