缘由
女朋友最近老是吵着要我写个APP给她,思来想去不知道写个啥好。一次偶然聊天的过程中,我不小心把我们在一起的时间给记错了,被迫写了两百字检讨。
原型
几番思考之后,就决定怎么简单怎么来叭,光速确定好原型图之后就开工叭。
背景部分
用水波纹动画当作背景,直接约束布局包自定义控件
setContent {
ConstraintLayout(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
) {
CustomWaveBgView(
Modifier
.fillMaxHeight()
.fillMaxWidth()
)
}
}
自定义波纹控件,用Compose自带的 Canvas控件,完整代码
object CustomView {
private val animatorValue: MutableState<Float> = mutableStateOf(0f)
val points = ArrayList<Point>()
@Composable
fun CustomWaveBgView(modifier: Modifier) {
val animator = ObjectAnimator.ofFloat(this, "value", 0f, 200f)
val paint = Paint()
for (i in 0 until 5) {
val point = Point()
points.add(point)
}
paint.apply {
strokeWidth = 5f
style = PaintingStyle.Stroke
}
animator.apply {
repeatCount = -1
duration = 5000
interpolator = LinearInterpolator()
start()
}
Canvas(
modifier
) {
drawIntoCanvas {
for (point in points) {
if (point.isStart) {
paint.color = Color(point.color)
paint.alpha = (200 - point.radus) / 200
it.drawCircle(
Offset(point.x.toFloat(), point.y.toFloat()),
point.radus,
paint
)
}
}
animatorValue.value
}
}
}
private fun setValue(vararg: Float) {
animatorValue.value = vararg
for (point in points) {
if (point.startProgress == vararg.toInt()) {
point.startAnimator()
}
}
}
}
创建了五个point,在每个Point里面开启了一个属性动画,不断的更改半径 radius 的值
在自定义的View中,创建了一个动画,保证Canvas控件一直去刷新(感觉这种方式不太好,实际上animatorValue这个变量根本没有使用,但是目前还是入门阶段,还没找到比较好的方式)
Point代码:
class Point {
private val animator = ObjectAnimator.ofFloat(this, "value", 0f, 200f)
var x: Int
var y: Int
var startProgress: Int
var isStart = false
var radus = 0f
var color:Int
init {
x = 220 + (Math.random() * (getScreenWidth() - 400)).toInt()
y = 220 + (Math.random() * (getScreenHeight() - 400)).toInt()
color = Color.rgb(
(Math.random() * 255).toFloat(),
(Math.random() * 255).toFloat(),
(Math.random() * 255).toFloat()
)
startProgress = (Math.random() * 200).toInt()
animator.duration = 5000
animator.interpolator = DecelerateInterpolator()
animator.addListener(object:AnimatorListener{
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
isStart = false
startProgress = (Math.random() * 200).toInt()
}
override fun onAnimationCancel(animation: Animator) {
}
override fun onAnimationRepeat(animation: Animator) {
}
})
}
private fun reset() {
x = 220 + (Math.random() * (getScreenWidth() - 400)).toInt()
y = 220 + (Math.random() * (getScreenHeight() - 400)).toInt()
radus = 0f
}
fun startAnimator() {
reset()
isStart = true
animator.start()
}
private fun setValue(vararg: Float) {
radus = vararg
}
}
动画的最大值是直接写的数字,没有做统一管理,其实不太好,但是这些不是compose里面的内容,所以能跑就行叭。
最后的效果