compose自定义布局和动画的结合-摩天轮效果

简介: compose自定义布局和动画的结合-摩天轮效果

先看最终效果效果


image.png


Layout作用


自定义布局使用Layout实现,Layout可以布局多个可组合项。我们可以通过Layout实现各种复杂的自定义布局。ColumnRow都是通过Layout实现的


Layout api讲解


下面的代码摘抄自官方,实现了一个Column的效果

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
      //placeables是测量完的子view列表
       val placeables = measurables.map { measurable ->
            measurable.measure(constraints)//根据父布局约束测量
        }
        layout(constraints.maxWidth, constraints.maxHeight) {//maxWidth就是父布局的最大宽度,layout函数是用来布局摆放子布局的
            var yPosition = 0
            placeables.forEach { placeable ->
                placeable.placeRelative(x = 0, y = yPosition)//根据相对位置摆放子view
                yPosition += placeable.height
            }
        }
    }
}
复制代码
  • content: 被传递给子项的view函数
  • measurables: 所有可被测量的布局列表
  • constraints: 来自于父布局的约束条件


实现自定义布局


本例中我们实现了这样一个效果,传入n个子布局,然后将这个子布局使用自定义布局Layout实现原型摆放的效果。代码如下

@Composable
private fun startAnimLayoutReal(
    modifier: Modifier = Modifier,
    degree: Double,
    content: @Composable () -> Unit
) {
    Layout(content = content, modifier = modifier) { measurable, constraint ->
        val placeable = measurable.map {
            it.measure(constraint)
        }
        val perDegree = 2 * Math.PI / placeable.size//两个子view之间的弧度间隔
        val width = 300//摆放大圆的半径
        val startX = 450//圆心x坐标
        val startY = 450//圆心y坐标
        var currentDegree = degree//当前所属的弧度
        layout(constraint.maxWidth, constraint.maxHeight) {
            placeable.forEach {
                val x = Math.sin(currentDegree) * width + startY
                val y = Math.cos(currentDegree) * width + startX
                it.placeRelative(x = x.toInt(), y = y.toInt())//根据控件当前弧度将控件摆放在大圆的对应位置上
                currentDegree += perDegree.toFloat()//弧度加一,摆放下一个子布局
            }
        }
    }
}
复制代码


给布局加上摩天轮的旋转效果

我们使用rememberInfiniteTransition实现动画无限执行的效果,这样多个子view围绕之圆心进行无限旋转,看起来就像一个大摩天轮

@Composable
fun starLayout() {
    val size = 30.dp
    Column {
        buildTopBar(title = "摩天轮")
        startLayoutReal {
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
            Image(
                modifier = Modifier.size(size),
                painter = painterResource(id = R.drawable.apple),
                contentDescription = ""
            )
        }
    }
}
@Composable
private fun startLayoutReal(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
    val transition = rememberInfiniteTransition()
    val currentDegree by transition.animateFloat(
        initialValue = 0f, targetValue = 2 * Math.PI.toFloat(), animationSpec = infiniteRepeatable(
            animation = tween(10 * 1000, easing = LinearEasing),
            repeatMode = RepeatMode.Restart
        )
    )
    startAnimLayoutReal(modifier = modifier, currentDegree.toDouble(), content = content)
}
@Composable
private fun startAnimLayoutReal(
    modifier: Modifier = Modifier,
    degree: Double,
    content: @Composable () -> Unit
) {
    Layout(content = content, modifier = modifier) { measurable, constraint ->
        val placeable = measurable.map {
            it.measure(constraint)
        }
        val perDegree = 2 * Math.PI / placeable.size//两个子view之间的弧度间隔
        val width = 300//摆放大圆的半径
        val startX = 450//圆心x坐标
        val startY = 450//圆心y坐标
        var currentDegree = degree//当前所属的弧度
        layout(constraint.maxWidth, constraint.maxHeight) {
            placeable.forEach {
                val x = Math.sin(currentDegree) * width + startY
                val y = Math.cos(currentDegree) * width + startX
                it.placeRelative(x = x.toInt(), y = y.toInt())//根据控件当前弧度将控件摆放在大圆的对应位置上
                currentDegree += perDegree.toFloat()//弧度加一,摆放下一个子布局
            }
        }
    }
}



相关文章
|
Java Shell 网络安全
springboot 远程调用shell脚本,环境为windows
本文是博主学习SpringBoot的记录,希望对大家有所帮助。
1335 0
springboot 远程调用shell脚本,环境为windows
|
编解码 Android开发
Android 常用布局单位区别(dp、sp、px、pt、in、mm)
Android 常用布局单位区别(dp、sp、px、pt、in、mm)
1798 0
|
机器学习/深度学习 运维 算法
梯度&散度&旋度&峰度&偏度你分得清楚吗?驻点&鞍点你分得清楚吗?曲率&斜率你分得清楚吗?
本文介绍了四种常见的物理量:加速度,速度,位移和力学功。详细介绍了它们的定义、计算以及在物理学和工程学领域中的应用。此外,本文还介绍了四种与物理量相关的概念:向量、标量、质量和密度。 数学,物理,机器学习领域常见概念区分
3818 0
|
1月前
|
人工智能 弹性计算 搜索推荐
开源 OpenClaw 实战:30 分钟在阿里云部署你的第一个 AI Agent
阿里云推出OpenClaw一键部署方案,仅需9.9元即可在轻量应用服务器、无影云电脑或ECS上快速搭建本地优先AI助理。三步完成:选环境→一键安装配置(集成百炼API)→个性化任务分配,零代码轻松启用智能体。
417 4
Jetpack Compose中ViewModel、Flow、Hilt、Coil的使用
Jetpack Compose中ViewModel、Flow、Hilt、Coil的使用
2007 0
Jetpack Compose中ViewModel、Flow、Hilt、Coil的使用
|
缓存 Java 数据库
Android的ANR原理
【10月更文挑战第18天】了解 ANR 的原理对于开发高质量的 Android 应用至关重要。通过合理的设计和优化,可以有效避免 ANR 的发生,提升应用的性能和用户体验。
780 56
|
机器学习/深度学习 自然语言处理 PyTorch
精通 Transformers(一)(2)
精通 Transformers(一)
677 4
|
机器学习/深度学习 算法 安全
从方向导数到梯度:深度学习中的关键数学概念详解
方向导数衡量函数在特定方向上的变化率,其值可通过梯度与方向向量的点积或构造辅助函数求得。梯度则是由偏导数组成的向量,指向函数值增长最快的方向,其模长等于最速上升方向上的方向导数。这两者的关系在多维函数分析中至关重要,广泛应用于优化算法等领域。
1776 36
从方向导数到梯度:深度学习中的关键数学概念详解
|
前端开发 JavaScript
轻松上手:基于single-spa构建qiankun微前端项目完整教程
轻松上手:基于single-spa构建qiankun微前端项目完整教程
834 0
|
Java API Android开发
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
964 0

热门文章

最新文章

下一篇
开通oss服务