Android炫酷消失动画-ThanosSnap


该动画效果灵感来源于《复仇者联盟3》里灭霸打完响指之后,复仇者们消失的场景。

在这里插入图片描述
下面看下我们自己实现的效果:

在这里插入图片描述
这里不是只对ImageView做了动画,而是对包含ImageView的父view做动画。
该动画可用在绝大部分view和viewgroup上,上面的例子就是对Recyclerview中的Item做了动画。
已经将该动画效果开源到了Github,并且可以通过gradle直接引用。

github地址

使用方法

导入依赖

在根目录的build.gradle文件下添加:

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

在app目录的build.gradle文件下添加:

	dependencies {
	        implementation 'com.github.Brooks0129:ThanosSnap:v1.0'
	}

调用

Kotlin调用:

        val disappearView = DisappearView.attach(activity)
        disappearView.execute(view, 
            duration = 4000, 
            interpolator = AccelerateInterpolator(0.5f),
            needDisappear = true)

DisappearView.attach(activity)里应该传递一个activity实例。
调用disappearView.execute表示开始执行动画,下面解释各个参数的含义。

  • view,表示需要执行动画的view,可以是单个的view,也可以是viewgroup,没有限制
  • duration,表示动画执行的时间,可以不填,默认是4m
  • interpolator,动画插值器,可以不填,默认是AccelerateInterpolator(0.5f)
  • needDisappear,表示执行动画的时候,原view是否要消失,可以不填,默认消失

如果是java调用,可以选择相应的重载方法。

原理分析

首先获取要做动画的view的截图。

   private fun createBitmapFromView(view: View): Bitmap? {
       view.clearFocus()
       val bitmap = createBitmapSafely(
           view.width,
           view.height, Bitmap.Config.ARGB_8888, 1
       )
       if (bitmap != null) {
           synchronized(sCanvas) {
               val canvas = sCanvas
               canvas.setBitmap(bitmap)
               view.draw(canvas)
               canvas.setBitmap(null)
           }
       }
       return bitmap
   }

   private fun createBitmapSafely(width: Int, height: Int, config: Bitmap.Config, retryCount: Int): Bitmap? {
       try {
           return Bitmap.createBitmap(width, height, config)
       } catch (e: OutOfMemoryError) {
           e.printStackTrace()
           if (retryCount > 0) {
               System.gc()
               return createBitmapSafely(width, height, config, retryCount - 1)
           }
           return null
       }

   }

拿到对应的bitmap,然后将Bitmap添加到原view的位置,添加方法是找到id为Window.ID_ANDROID_CONTENTrootview,在rootview上添加一个新view,这个新view负责将bitmap画出来。
接下来是bitmap动画部分。
将Bitmap分成几十个小bitmap。



    private fun generateElement(i: Int, j: Int, elementLen: Int, bitmap: Bitmap): Element? {
        val element = Element()
        element.row = i
        element.col = j
        element.x = i * elementLen + mRect.left
        element.y = j * elementLen + mRect.top
        element.originX = element.x
        element.originY = element.y
        if (element.x + elementLen <= mRect.right) {
            element.w = elementLen
        } else {
            element.w = mRect.right - element.x
        }
        if (element.w <= 0) {
            return null
        }
        if (element.y + elementLen <= mRect.bottom) {
            element.h = elementLen
        } else {
            element.h = mRect.bottom - element.y
        }

        if (element.h <= 0) {
            return null
        }
        element.alpha = 1F
        val path = Path()

        path.moveTo(element.x.toFloat(), element.y.toFloat())
        path.rQuadTo(
            (Random.nextInt(150)).toFloat(),
            (-Random.nextInt(150)).toFloat(),
            (100 + Random.nextInt(150)).toFloat(),
            (-100 - Random.nextInt(150)).toFloat()
        )
        element.path = path

        element.bitmap = Bitmap.createBitmap(bitmap, i * elementLen, j * elementLen, element.w, element.h)

        return element
    }

每一个小bitmap在生成的时候都确定了当前的位置、透明度及运动轨迹。
最后我们根据属性动画,即可确定每一个bitmap当前的状态。

具体代码参见源码。

限制与todo

限制

DisappearView.attach(activity)只能传递一个activity,所以如果当前如果context不是activity,那么动画暂时无法支持。比如说在Dialog中。

Todo

支持Dialog等非Activity

动画方向多样

每一个元素样式多样

目前每一个运动的元素都是矩形,接下来会支持圆形和自定义图形。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页