Compose自定义View实现宇智波斑写轮眼

 更新时间:2023年02月12日 11:32:03   作者:cxy107750  
这篇文章主要为大家介绍了Compose自定义View实现宇智波斑写轮眼示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

本章节是Compose自定义绘制的第二章,画的是一个之前设计给的一个比较复杂的,设计所谓的会呼吸的动画,那时候实现花了蛮长的时间,搬着电脑跟设计一帧一帧地对,没多久后来需求就被拿掉了,至于文章的标题哈哈随意起了一个,长得有点像而已。

Compose的实现,图形本身跟上一章节的LocationMarker其实差不太多,倒过来了而已,调整了P1跟P3, 基本图形的Path,这里不再做介绍,读者也可以去看代码实现。主要介绍一下动画吧。

首先看一下gif动图:

整个图形分三层,最底层是灰色的背景,没有动画实现。

先实现功能效果

第二层是一个层变的动画,每层有个delay的不同延迟,对alpha最一个ObjectAnimator.ofFloat(water1, "alpha", 0f, 0.5f, 0.2f, 1f)渐变的动画,0.5f 到0.2f, 再到1f这个地方展现出所谓的呼吸的感觉。Compose目前写的不多,有些冗余代码没有抽象,先实现了功能效果。

@Composable
fun drawWaterDrop(){
  val waterDropModel by remember {
  mutableStateOf(WaterDropModel.waterDropM)
  }
  val color1 = colorResource(id = waterDropModel.water1.colorResource)
  val color2 = colorResource(id = waterDropModel.water2.colorResource)
  val color3 = colorResource(id = waterDropModel.water3.colorResource)
  val color4 = colorResource(id = waterDropModel.water4.colorResource)
  val color5 = colorResource(id = waterDropModel.water5.colorResource)
  val color6 = colorResource(id = waterDropModel.water6.colorResource)
  val color7 = colorResource(id = waterDropModel.water7.colorResource)
  val color8 = colorResource(id = waterDropModel.water8.colorResource)
  val animAlpha1 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha2 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha3 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha4 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha5 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha6 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha7 = remember { Animatable(0f, Float.VectorConverter) }
  val animAlpha8 = remember { Animatable(0f, Float.VectorConverter) }
    LaunchedEffect(Unit){
        animAlpha1.animateTo(1f, animationSpec = myKeyframs(0))
    }
    LaunchedEffect(Unit){
        animAlpha2.animateTo(1f, animationSpec = myKeyframs(1))
    }
    LaunchedEffect(Unit){
        animAlpha3.animateTo(1f, animationSpec = myKeyframs(2))
    }
    LaunchedEffect(Unit){
        animAlpha4.animateTo(1f, animationSpec = myKeyframs(3))
    }
    LaunchedEffect(Unit){
        animAlpha5.animateTo(1f, animationSpec = myKeyframs(4))
    }
    LaunchedEffect(Unit){
        animAlpha6.animateTo(1f, animationSpec = myKeyframs(5))
    }
    LaunchedEffect(Unit){
        animAlpha7.animateTo(1f, animationSpec = myKeyframs(6))
    }
    LaunchedEffect(Unit){
        animAlpha8.animateTo(1f, animationSpec = myKeyframs(7))
    }
  Canvas(modifier = Modifier.fillMaxSize()){
  val contentWidth = size.width
  val contentHeight = size.height
  withTransform({
  translate(left = contentWidth / 2, top = contentHeight / 2)}) {
  drawPath(AndroidPath(waterDropModel.water8Path), color = color8, alpha = animAlpha8.value)
  drawPath(AndroidPath(waterDropModel.water7Path), color = color7, alpha = animAlpha7.value)
  drawPath(AndroidPath(waterDropModel.water6Path), color = color6, alpha = animAlpha6.value)
  drawPath(AndroidPath(waterDropModel.water5Path), color = color5, alpha = animAlpha5.value)
  drawPath(AndroidPath(waterDropModel.water4Path), color = color4, alpha = animAlpha4.value)
  drawPath(AndroidPath(waterDropModel.water3Path), color = color3, alpha = animAlpha3.value)
  drawPath(AndroidPath(waterDropModel.water2Path), color = color2, alpha = animAlpha2.value)
  drawPath(AndroidPath(waterDropModel.water1Path), color = color1, alpha = animAlpha1.value)
  }
  }
}
private fun myKeyframs(num:Int):KeyframesSpec<Float>{
    return keyframes{
        durationMillis = 3000
        delayMillis = num * 2000
        0.5f at 1000 with LinearEasing
        0.2f at 2000 with LinearEasing
    }
}

调用传入不同的delay值

然后就是外层扫光的动画,像探照灯一样一圈圈的扫,一共扫7遍,代码跟层变动画差不多,也是对alpha值做渐变,目前代码是调用扫光动画7次,后续看看如何优化性能。每次调用传入不同的delay值即可。

@Composable
fun drawWaterDropScan(delayTime:Long){
    val waterDropModel by remember {
        mutableStateOf(WaterDropModel.waterDropMScan)
    }
    val color1 = colorResource(id = waterDropModel.water1.colorResource)
    val color2 = colorResource(id = waterDropModel.water2.colorResource)
    val color3 = colorResource(id = waterDropModel.water3.colorResource)
    val color4 = colorResource(id = waterDropModel.water4.colorResource)
    val color5 = colorResource(id = waterDropModel.water5.colorResource)
    val color6 = colorResource(id = waterDropModel.water6.colorResource)
    val color7 = colorResource(id = waterDropModel.water7.colorResource)
    val color8 = colorResource(id = waterDropModel.water8.colorResource)
    val animAlpha2 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha3 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha4 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha5 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha6 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha7 = remember { Animatable(0f, Float.VectorConverter) }
    val animAlpha8 = remember { Animatable(0f, Float.VectorConverter) }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(1f, 350) }
        animAlpha2.animateTo(0f, animationSpec = myKeyframs2(700, 0, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.8f, 315) }
        animAlpha3.animateTo(0f, animationSpec = myKeyframs2(630, 233, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.55f, 315) }
        animAlpha4.animateTo(0f, animationSpec = myKeyframs2(630, 383, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.5f, 325) }
        animAlpha5.animateTo(0f, animationSpec = myKeyframs2(650, 533, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.45f, 325) }
        animAlpha6.animateTo(0f, animationSpec = myKeyframs2(650, 667, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.35f, 283) }
        animAlpha7.animateTo(0f, animationSpec = myKeyframs2(567, 816, map))
    }
    LaunchedEffect(Unit){
        delay(delayTime)
        val map = mutableMapOf<Float, Int>().apply { put(0.3f, 216) }
        animAlpha8.animateTo(0f, animationSpec = myKeyframs2(433, 983, map))
    }
  Canvas(modifier = Modifier.fillMaxSize()){
  val contentWidth = size.width
  val contentHeight = size.height
  withTransform({
  translate(left = contentWidth / 2, top = contentHeight / 2)
  }) {
  drawPath(AndroidPath(waterDropModel.water8Path), color = color8, alpha = animAlpha8.value)
  drawPath(AndroidPath(waterDropModel.water7Path), color = color7, alpha = animAlpha7.value)
  drawPath(AndroidPath(waterDropModel.water6Path), color = color6, alpha = animAlpha6.value)
  drawPath(AndroidPath(waterDropModel.water5Path), color = color5, alpha = animAlpha5.value)
  drawPath(AndroidPath(waterDropModel.water4Path), color = color4, alpha = animAlpha4.value)
  drawPath(AndroidPath(waterDropModel.water3Path), color = color3, alpha = animAlpha3.value)
  drawPath(AndroidPath(waterDropModel.water2Path), color = color2, alpha = animAlpha2.value)
  drawPath(AndroidPath(waterDropModel.water1Path), color = color1)
  }
  }
}
private fun myKeyframs2(durationMillisParams:Int, delayMillisParams:Int, frames:Map<Float, Int>):KeyframesSpec<Float>{
    return keyframes{
        durationMillis = durationMillisParams
        delayMillis = delayMillisParams
        for ((valueF, timestamp) in frames){
           valueF at timestamp
        }
    }
}
@Preview
@Composable
fun WaterDrop(){
    Box(modifier = Modifier.fillMaxSize()){
        drawWaterDropBg()
        drawWaterDrop()
        for (num in 1 .. 7){
            drawWaterDropScan(delayTime = num * 2000L)
        }
    }
}

代码跟LocationMarker在一个Project里面,暂时没有添加导航。github.com/yinxiucheng… 下的CustomerComposeView.

以上就是Compose自定义View实现宇智波斑写轮眼的详细内容,更多关于Compose自定义View的资料请关注脚本之家其它相关文章!

相关文章

  • Android中实现GPS定位的简单例子

    Android中实现GPS定位的简单例子

    这篇文章主要介绍了Android中实现GPS定位的简单例子,例子逻辑清晰,但相对简单了些,需要的朋友可以参考下
    2014-07-07
  • 详解Activity之singletast启动模式及如何使用intent传值

    详解Activity之singletast启动模式及如何使用intent传值

    在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中
    2015-11-11
  • Android App中ViewPager所带来的滑动冲突问题解决方法

    Android App中ViewPager所带来的滑动冲突问题解决方法

    Android中我们经常使用ViewPager配合Fragment实现视图滑动,但在实际操作中又会经常发生方向上的冲突问题,这里我们就来总结一下Android App中ViewPager所带来的滑动冲突问题解决方法:
    2016-06-06
  • Android手机联系人带字母索引的快速查找

    Android手机联系人带字母索引的快速查找

    这篇文章主要为大家详细介绍了Android手机联系人带字母索引的快速查找实现方法,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • Android中Parcel用法详解

    Android中Parcel用法详解

    这篇文章主要介绍了Android中Parcel用法,结合实例形式较为详细的分析了Parcel数据容器的原理与使用方法,需要的朋友可以参考下
    2016-06-06
  • Android开发之微信底部菜单栏实现的几种方法汇总

    Android开发之微信底部菜单栏实现的几种方法汇总

    这篇文章主要介绍了Android开发之微信底部菜单栏实现的几种方法,下面小编把每种方法通过实例逐一给大家介绍,需要的朋友可以参考下
    2016-09-09
  • Android Studio 3.6 正式版终于发布了,快来围观

    Android Studio 3.6 正式版终于发布了,快来围观

    Android Studio 3.6 正式版终于发布了,值得兴奋呀,毕竟 3.5 大版本更新也已经差不多半年了,撒花撒花!这次更新又更新了什么呢?快来跟随小编一起看看吧
    2020-02-02
  • Android Studio查看Android 5.x源码的步骤详解

    Android Studio查看Android 5.x源码的步骤详解

    Google为Android开发者带来Android Studio,用来取代Eclipse。从Android Studio出现起,整机开发和Android源码阅读和编辑一定能用上它。这篇文章小编就带大家学习下如何使用Android Studio查看Android 5.x源码,有需要的可以参考借鉴。
    2016-09-09
  • Android项目基本结构详解

    Android项目基本结构详解

    这篇文章主要为大家详细介绍了Android项目基本结构,从最基本的内容讲起,带你逐步进入用C#进行Android应用开发的乐园,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • 解决EditText编辑时hint 在6.0 手机上显示不出来的问题

    解决EditText编辑时hint 在6.0 手机上显示不出来的问题

    下面小编就为大家带来一篇解决EditText编辑时hint 在6.0 手机上显示不出来的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05

最新评论