Jetpack Compose技术快速上手

一、什么是Compose?

Jetpack Compose 是Google新推出的用于构建原生 Android 界面的新工具包。它可简化并加快 Android 上的界面开发,使用更少的代码、强大的工具和直观的Kotlin API,快速让应用生动而精彩。

二、Compose的优势

  • 更少的代码
    在Android View系统,实现一个功能需要有XML和Kotlin/Java两部分,而在Compose中不需要拆分两部分,所有代码都使用同一种语言编写并且位于同一个文件中,往往复杂的功能几行代码就能搞定,因此Compose编写的代码简洁且易于维护。
    如:实现一个列表,简单几行代码
@Composable
fun Conversation(messages:List<Message>){
    LazyColumn {
        items(messages){ message->
            MessageCard(message)
        }
    }
}
  • 直观
    Compose使用声明性API,意味着只需描述界面,Compose会负责完成其余工作,应用状态发生变化时,界面会自动智能刷新。

  • 加快应用开发
    Compose兼容现有的所有代码,方便随时随地开始采用。借助全面的Android Studio支持和实时预览功能,可以更快的迭代。

  • 功能强大
    凭借对Android平台API的直接访问和对于Material Design、深色主题、动画等的内置支持,创建精美的应用。

三、开发环境准备

IDE版本:Android Studio Arctic Fox
语言:Kotlin

创建支持Jetpack Compose的新应用

打开Android Studio,依次执行File > New > New Project,在弹出的New Project弹窗中选择Empty Compose Activity,然后点击Next,设置对应Name、PackageName、和保存位置等信息,直接点击【Finish】即可完成Compose工程创建。
选择Empty Compose Activity界面

注:
1.仅支持Kotlin。
2.工程创建后会自动引入Compose相关基础库,如需其他工具包可在项目的Build.gradle配置。

四、Compose可组合函数和预览

新的Compose工程创建好后,在体验Compose开发前我们先来了解两个非常关键的注解。

★ 可组合函数
Jetpack Compose 是围绕可组合函数构建的。这些函数可让您以程序化方式定义应用的界面,只需描述应用界面的外观并提供数据依赖项,而不必关注界面的构建过程(初始化元素,将其附加到父项等)。如需创建可组合函数,只需将 @Composable 注解添加到函数名称中即可。

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

★ 预览函数
Android Studio允许在IDE中预览可组合函数,无需将应用安装到设备上。使用到的关键注解@Preview

扫描二维码关注公众号,回复: 15232470 查看本文章
@Preview
@Composable
fun DefaultPreview() {
    MessageCard("Android")
}

使用 Android Studio 预览可组合函数

五、布局

界面元素采用多层次布局,元素中包含其他元素。Compose中通过一个可组合函数调用其他可组合函数来构建界面。

  • 添加文本
    使用可组合函数Text添加一个文本
@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
}
  • 使用Column和Row
    针对多个元素时,怎么布局呢?此时就要用到Column和Row函数了。
    Column函数可以让元素垂直排列。Row函数可使元素水平排列。
@Composable
fun MessageCard(message:Message) {
    //行
    Row {
        //添加一个图片元素
        Image(
            //填充内容
            painter = painterResource(id = R.mipmap.ic_girl),
            contentDescription = "logo",
        )
        //列
        Column{
            Text(text = message.author)
            Text(text = message.body)
        }
    }
}

效果图

  • 添加图片元素
    添加图片元素采用的可组合函数为:Image,见上例子。
  • 使用修饰符配置布局
    在Compose中元素提供了修饰符,通过设置元素的modifier,可以更改元素的大小、布局、外观、互动。
    如下例子中,给Image增加修饰符
//添加一个图片
Image(
     //填充内容
     painter = painterResource(id = R.mipmap.ic_girl),
     contentDescription = "logo",
     //尺寸及形状
     modifier= Modifier
           .padding(top = 2.dp)
           .size(40.dp)                 //图像尺寸
           .clip(CircleShape)       //裁剪形状
    )

采用修饰符后的效果图

六、使用Material Design

Compose的许多界面元素都支持Material Design。
创建的项目中会生成默认主题,支持自定义MaterialTheme。

  • 设置一个Material主题样式
    override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContent {
              //设置主题
              JetpackDemoTheme {
                  ......
              }
          }
      }
    
  • 使用主题颜色
    以为图片添加圆形边框为例:
      //添加一个图片
    Image(
     //填充内容
     painter = painterResource(id = R.mipmap.ic_girl),
     contentDescription = "logo",
     //尺寸及形状
     modifier= Modifier
         .padding(top = 2.dp)
         .size(40.dp)             //图像尺寸
         .clip(CircleShape)       //形状
         .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)//边框样式
    )
    
    设置颜色后效果
  • 排版
    MaterialTheme 中提供了 Material 排版样式,只需将其添加到 Text 可组合项中即可。
    Text(
           text = message.author,
           color = MaterialTheme.colors.secondaryVariant,
           //添加MaterialTheme排版
           style = MaterialTheme.typography.subtitle2
        )
    
  • 设置边框形状
    //设置一个边框
    Surface(shape = MaterialTheme.shapes.medium,
        elevation = 2.dp,
        color = surfaceColor,
        modifier = Modifier.animateContentSize().padding(1.dp).clickable { isExpanded = !isExpanded }
      ){
    Text(text = msg.body)
    }
    
    效果图
  • 启用深色主题
    开发过程中,预览支持启用深色主题(即夜间模式),Jetpack Compose默认能处理深色主题。使用Material颜色、文本和背景时,系统会自动适应深色背景。
    启用方式如下:
    @Preview(name = "Light Mode")//白天模式
    @Preview(showBackground = true,uiMode = Configuration.UI_MODE_NIGHT_YES,name = "Dark Mode")//夜间模式
    @Composable
    fun DefaultPreview() {
        JetpackDemoTheme {
            MessageCard(Message("Android","Jetpack Compose"))
        }
    }
    

同时预览白天模式和夜间模式效果图

七、列表和动画

在实际应用中列表和动画非常常见,这里以简单学习如何利用Compose轻松创建列表和添加动画效果。

  • 创建消息列表
    Compose为我们提供了LazyColumnLazyRow可组合函数,分别对应垂直列表和水平列表。

    @Composable
    fun Conversation(messages:List<Message>){
        //垂直方向列表
        LazyColumn {
            items(messages){ message->
                MessageCard(message)
            }
        }
      }
    //定义数据类
    data class Message(val author: String, val body: String)
    

    静态列表图:
    列表效果图

  • 在展开消息时显示动画效果
    首先将Text的行数设置为一行,当点击时再全部展开。
    先使用可组合函数remember记录没行的展开状态,保存在mutableStateOf中,该值更新后,系统会自动智能重新绘制使用此状态的元素,这一过程又被称为重组

    @Composable
    fun MessageCard(message:Message) {
        ...
        var isExpanded by remember {
                  mutableStateOf(false)
              }
        ...
    }
    

    现在可以通过点击消息更改这个isExpanded变量值,然后根据这个值来修改消息的背景和工行效果。

    @Composable
    fun MessageCard(message:Message) {
        ...
        val surfaceColor: Color by animateColorAsState(
              if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
          )
        Column{
              ...
              //设置一个边框
              Surface(shape = MaterialTheme.shapes.medium,
                  elevation = 2.dp,
                  color = surfaceColor,
                  modifier = Modifier.animateContentSize()
                      .padding(1.dp)
                      //1.添加一个可点击事件
                      .clickable { isExpanded = !isExpanded }
              ){
                  Text(
                      text = message.body,
                      modifier = Modifier.padding(all = 4.dp),
                      //2.展开时设置行数
                      maxLines=if (isExpanded) Int.MAX_VALUE else 1,
                      //添加MaterialTheme排版
                      style = MaterialTheme.typography.body2
                  )
              }
              ...
        }
        ...
    }
    

    最后上一张带展开收起动画的gif效果图
    添加动画后的列表动态图

最后附上
github源码地址
gitee - 示例源码

猜你喜欢

转载自blog.csdn.net/seevc/article/details/122806249