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()//弧度加一,摆放下一个子布局
            }
        }
    }
}



相关文章
|
4月前
|
开发框架 Dart 容器
Flutter 自定义渐变按钮 GradientButton
Flutter 自定义渐变按钮 GradientButton Flutter 是一种流行的跨平台移动应用开发框架。Flutter 提供了许多内置的小部件,但有时您可能需要创建自己的小部件以满足特定的需求。这个文档将介绍如何创建一个自定义渐变按钮小部件 GradientButton。
|
11月前
|
存储 容器
flutter系列之:做一个修改组件属性的动画
什么是动画呢?动画实际上就是不同的图片连续起来形成的。flutter为我们提供了一个AnimationController来对动画进行详尽的控制,不过直接是用AnimationController是比较复杂的,如果只是对一个widget的属性进行修改,可以做成动画吗? 答案是肯定的,一起来看看吧。
|
开发者
Flutter小球弹跳动画
Flutter 的动画系统可以帮助开发者实现生动的游戏效果,例如物理效果、平移动画、旋转动画等等。以下是一个使用 Flutter 动画系统实现小球弹跳的示例代码
Flutter小球弹跳动画
|
XML 前端开发 API
Compose 页面切换动画
Compose 页面切换动画
647 0
Compose 页面切换动画
|
JSON 缓存 Android开发
玩转 Compose 中的 Lottie 动画
玩转 Compose 中的 Lottie 动画
243 0
玩转 Compose 中的 Lottie 动画
|
API 容器
Compose 动画艺术探索之属性动画
Compose 动画艺术探索之属性动画
148 0
|
Android开发 计算机视觉 Kotlin
Compose 实现下拉刷新和上拉加载
Compose 实现下拉刷新和上拉加载
1064 0
|
API 开发工具 git
Compose几个简单手势
Compose几个简单手势
504 0
Compose几个简单手势
|
Dart 开发者
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )(三)
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )(三)
147 0
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )(三)
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )(二)
【Flutter】Animation 动画 ( AnimatedBuilder 动画使用流程 | 创建动画控制器 | 创建动画 | 创建动画作用的组件 | 关联动画与组件 | 动画执行 )(二)
132 0