2024年最新【译】体验在Jetpack Compose使用Navigation_jatpack navigation,三面蚂蚁金服成功拿到offer

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

注意:Jetpack Compose最近已经发布了beta版本。这就意味着API的结构不会有太大的变动了。因此,现在这是学习怎么用Android开发下一代UI工具的时候了。Navigation是android开发的核心内容之一,所以你就好好看看本文吧。

使用Jetpack Compose Beta版本需要使用Android Studio Canary Arctic Fox的版本。

介绍

Jetpack Compose 是可以和Android组件比如Fragment进行交互的。因此如果你如果你已有一个现成的项目想要转到Jetpack Compose,你不需要做任何修稿。

但是如果你想迁移整个应用不再要任何Android组件比如Fragment,或者说你要用Compose创建一个全新的应用,那这篇文章就是为你准备的。

我们将用Navigation这个架构组件去实现页面之间的跳转。如果你还不熟悉Navigation的话,我强烈建议你阅读这篇文章:jitpack-navigation-component

用Compose创建一个有两个页面的应用

与传统的Android开发不同的是,Jetpack Compose没有Fragment,Activity这些约束。用Jetpack Compose可以用任意一个Composable的函数来表示页面的一部分或者是整个页面。如果你是从头开始创建一个项目的话,我建议你只用Composable,充分利用Compose强大的能力。

为了充分理解Compose的Navigation,让我们创建一个包含两个页面的Subscription:SubscriptionsListScreenSubscriptionDetailsScreen。看一下代码:

class Subscription(val name : String, val price : String, val details : String)

@Composable
fun SubscriptionsListScreen(subscriptionslist : List<Subscription>){
    LazyColumn(
        modifier = Modifier.fillMaxWidth()
    ){
        items(subscriptionslist){subscription->
            SubscriptionsListItem(subscription)
        }
    }
}

@Composable
fun SubscriptionsListItem(subscription : Subscription){
    Column(
        modifier = Modifier.fillMaxWidth()
    ){
        Text(text = subscription.name, style = MaterialTheme.typography.h6)
    }
}

@Composable
fun SubscriptionDetailsScreen(subscriptionName : String){
    Column(
        modifier = Modifier.fillMaxWidth()
    ){
        val subscription = SubscriptionsDatabase.subsList.single { it.name.equals(subscriptionName, true)  }
        Text(text = subscription.name, style = MaterialTheme.typography.h5)
        Text(text = subscription.name, style = MaterialTheme.typography.body1)
        Text(text = subscription.details, style = MaterialTheme.typography.body2)
    }
}
复制代码

这段代码里面,有3个Composable函数代表了两个页面:

  • SubscriptionsListScreen是表示subscription列表页面的Composable,参数是订阅列表。
  • SubscriptionsListItem表示每个订阅项的UI,参数是一个Subscription类。
  • SubscriptionDetailsScreen表示订阅的详情,从列表可以调到详情页,参数是Subscription类。

这里,SubscriptionsListScreen和SubscriptionDetailsScreen分别表示列表和详情页。和传统的开发相比它们和Activity和Fragment是一样的。SubscriptionsListItem表示了页面的一部分,就想RecyclerView的Adapter Item一样。

我们的任务是在这两个页面之间用Navigation框架实现跳转,同时传递订阅的信息。

集成

为了让Navigation能在Compose里面工作起来,我们得加上下面的依赖。有了这个依赖Navigation才能和Composable函数适配:

implementation "androidx.navigation:navigation-compose:1.0.0-alpha08"
复制代码
Navigation框架

在了解Navigation组件之前,你得知道Android 里的remember是啥。在声明式UI系统里面,代码本身就是用来描述UI的。需要在任何时候都能表示UI而不仅仅是在初始化的时候。

为了达到这个目的,我们需要尽可能简单有效的维护一个状态,Jetpack Compose提供了remember。remember会保持对状态的跟踪。为了更好的理解和学习remember和其他Jetpack Compose的组件,可以阅读下面的文章Jetpack Compose 组件(Part 2)

现在可以开始对Composable实现一个Navigation框架了。通过上面集成的库,Navigation组件已经完全适配Composable了。

首先我们需要学习的是remmeberNavController这个Composable函数,它创建了一个NavHostController来处理ComposeNavigator。我们可以用NavHostController来实现两个Composable函数之间的跳转。

val navController = rememberNavController()
复制代码

接着,我们需要创建一个包含所有页面的对象的密封类。对于我们的例子,我们有两个对象:SubscriptionsList和SubscriptionDetails。看一下代码:

sealed class Screen(val route: String, @StringRes val resourceId: Int) {
    object Home : Screen("SubscriptionsList", R.string.subs_list)
    object Details : Screen("SubscriptionDetails", R.string.sub_details)
}
复制代码

现在可以创建主Composable了,将所有的compose页面嵌套到NavHost这个Composable函数里面。一旦这个被调用,任何只要在NavGraphBuilder里面配置的Composable都可以通过navController进行跳转。在我们的例子里面,有两个页面需要在NavHost里面声明,如下所示:

@Composable
fun SubscriptionsMain() {
    val navController = rememberNavController()
    NavHost(navController, startDestination = Screen.Home.route) {
        composable(Screen.Home.route) {
            SubscriptionsListScreen( SubscriptionsDatabase.subsList)
        }
        composable(Screen.Details.route) {
            SubscriptionDetailsScreen( /* TODO paramter implementation pending */)
        }
    }
}
复制代码

这里的Composable是NavGraphBuilder的扩展函数,用来往NavGraphBuilder上添加Composable的。下一步就是传递参数。SubscriptionDetailsScreen组合函数需要一个Subscription的数据类来展示详情。

脑子里想象一下我们需要把SubscriptionsMain的组合函数渲染到MainActivity这个类。

为了支持参数和deep link,Composable函数有两个默认值是emptyList的list类型的参数。直接看下这个函数到底长啥样:

public fun NavGraphBuilder.composable(
    route: String,
    arguments: List<NamedNavArgument> = emptyList(),
    deepLinks: List<NavDeepLink> = emptyList(),
    content: @Composable (NavBackStackEntry) -> Unit
)
复制代码

这里的argumens和deepLinks是可选的。在我们的例子里面,我们需要将参数传递给详情页,首页两个参数都不需要。基本上,我们需要将订阅的名称用字符串类型作为参数传递进去,看一下代码:

@Composable
fun SubscriptionsMain() {
    val navController = rememberNavController()
    NavHost(navController, startDestination = Screen.Home.route) {
        composable(Screen.Home.route) {
            SubscriptionsListScreen( SubscriptionsDatabase.subsList)
        }
        composable(Screen.Details.route,
            arguments = listOf(navArgument("name") { type = NavType.StringType }) {
            SubscriptionDetailsScreen( it.arguments?.getString("name") ?: 0)
        }
    }
}
复制代码

如果你已经看了我们更新的SubscriptionsMain函数的话,在详情页的Composable里面,我们已经声明了订阅的名称作为一个字符串类型,并且我们在lambda的表达式里面用到了。

实现Composable函数之间的跳转

总的来说,想实现任何Android组件之间的跳转,需要借助navController。Composable函数也一样。从一个Composable触发或者是启动另一个Composable都需要navController。

与传统的方式不同的是,Composable还不能直接找到navController。因此需要将我们在SubscriptionsMain中创建的navController传递进去,目标Composable函数不要用navController作为一个入参。在我们的例子里面,SubscriptionsListScreen和SubscriptionsListItem需要navController。看一下修改完的Composable:

@Composable
fun SubscriptionsListScreen(navController: NavController, subscriptionslist : List<Subscription>){


**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

![](https://img-blog.csdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
![img](https://img-blog.csdnimg.cn/img_convert/f35101bab08946dabe841ceadc00e5e2.png)
![img](https://img-blog.csdnimg.cn/img_convert/b79f3de55da0c5e9af31c334d8ab7278.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**

15710894969)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**

  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值