1. 常识拆解

从本文你能够学习到以下常识点:

  • 如何快速学会用Compose进行布局
  • 了解Composable函数中数据驱动UI的编程思维, 了解remember函数的效果
  • 了解函数副效果, 编写动画

1.1 布局

“一键三连”由三个部分构成: 点赞及点赞数、投币及投币数和保藏及保藏数, 三个部分横向排布, 因此能够用Row来包裹

Row {
 点赞组件
 投币组件
 保藏组件
}

以点赞为例, 它是上下结构, 且数字对齐于图标, 在传统Android View系统中, 咱们很快会想到束缚布局然后使其左面对齐左面, 右边对其右边, 幸亏的是Compose中也有constraintlayout-compose库, 所以咱们引入该库

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

该库与咱们以前运用束缚布局时的思维是相同的:

  1. ConstraintLayout包裹子元素
  2. 给每个子元素生成id, 此处叫createRefs创建引证
  3. 将子元素对其parent, 子元素之间再按需对齐
ConstraintLayout {
 // 给点赞图标、数量文本创建引证, 此处运用了解构声明语法
 val (refThumb, refCounter) = createRefs()
 // 将点赞图标引证的左、上、右对齐`parent`的左、上、右边
 Icon(modifier = Modifier.constrainAs(refThumb) {
                  start.linkTo(parent.start)
                 top.linkTo(parent.top)
                 end.linkTo(parent.end)
           })
 // 将文本引证的左右两头对其`parent`,将顶部对齐图标的底部
 Text(modifier = Modifier.constrainAs(refCounter) {
          start.linkTo(parent.start)
          end.linkTo(parent.end)
          top.linkTo(refThumb.bottom)
          })
}

再如法炮制投币和保藏组件,这样”一键三连”就布局好了

Row {
 ConstraintLayout {
  Icon()
  Text()
  }
 ConstraintLayout {
  Icon()
  Text()
  }
 ConstraintLayout {
  Icon()
  Text()
  }
}

1.2 用状况驱动UI

在咱们传统的Android View系统中,咱们给TextView设置文本一般这么做:

  1. 找到这个view: textView = findViewId(id)
  2. 设置view的特点: textView.setText("67")

而在compose UI编程中,状况指明了UI的当前特点,状况改动UI随之改动。用一个表达式表明为:

UI=composable(state)UI = composable(state)

因此,

  1. 咱们经过remember声明一个状况,它表明会改动的文本内容, 而且它能够跨越composable函数的重组阶段而不被从头初始化(这是要害):
var thumbCount by remember { mutableStateOf(66) }
  1. 将状况设置给Text:
Text(thumbCount.toString())
  1. 改动状况,composable函数会进行重组,然后主动改动文本内容
Text(thumbCount.toString(), modifier = Modifier.clickable {
                                // 点击时将数量+1
                     thumbCount = thumbCount + 1
                    })

1.3 设置长按事情,绘制动画

“一键三连”时,长准时开端呈现圆弧进展条,而且跟着时间圆弧扫过的视点从0-360, 直到变成完好的圆圈⭕️,它有以下特点

  1. 圆弧增加是连续的,或者说看似连续的, 每一小段时间就增加一点圆弧视点
  2. 圆弧视点是一个状况,由于他不能由于函数重组而被从头初始化
  3. 动画是能够被打断的且被反转的,松手后不再增加视点而是减小视点,因此圆弧视点的改动能够被放在一个协程中运行, 由于它能够很容易被撤销并从头开端
// 三连进展 从0到-360度,逆时针
var hitProgress by remember { mutableStateOf(0) }
var hitJob by remember { mutableStateOf<Job?>(null) }
      ...
      // 触摸事情: ACTION_DOWN
      hitJob?.cancel()
      hitJob = scope.async {
        // 手指按下后,逐渐削减hitProgress,使圆弧视点逆时针增加
        while (hitProgress > -360) {
          delay(15)
          hitProgress -= 4
        }
      }
      ...
      // 触摸事情: ACTION_UP
      hitJob?.cancel()
      hitJob = scope.async {
        // 手指抬起时, 增加hitProgress,使圆弧逐渐缩短
        while (hitProgress < 0) {
          delay(8)
          hitProgress += 4
        }
      }
...
// 画一段圆弧,从-90度开端,扫过hitProgress的视点, 圆弧的弧长会主动跟从hitProgress的改动而改动
drawArc(
  startAngle = -90f,
  sweepAngle = hitProgress.toFloat(),
)

2. 总结

经过以上的比如,咱们能够发现,compose比较传统view在布局、动画方面会更为快速便捷。但也与view系统有很大的不同,主要体现在:

  1. 无法拿到view对象,来改动本身特点,而是经过状况依赖来驱动本身特点
  2. 动画的完成经过函数副效果来完成,它又与协程联络严密

源码地址: Github

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。