Android动画全篇系列(八)——揭露动画
文章目录
- 一、揭露动画(CircularReveal)介绍
- 二、介绍和简单实现
- 1、简单介绍
- 2、简单实现
- 3、小小的优化
- 4、简单的看看源码
- 三、结合Activity
- 1、获取手指点击的位置并打开Activity
- 2、第二个Activity的代码
- 3、优化
一、揭露动画(CircularReveal)介绍
当您显示或隐藏一组界面元素时,揭露动画可为用户提供视觉连续性。让您能够为裁剪圆形添加动画以揭露或隐藏视图。此动画在 ViewAnimationUtils 类中提供,适用于 Android 5.0(API 级别 21)及更高版本。——亲爸爸谷歌
揭露动画的实现比较简单,只需要几行代码就可以完成。
所以我们直接先看效果图:

二、介绍和简单实现
1、简单介绍
创建一个揭露动画需要用到系统提供的ViewAnimationUtils类,这个类是个final类,并且私有化了构造方法,对外仅仅提供一个方法createCircularReveal(),所以我们可以直接使用下方一行代码就可以创建揭露动画:
val anim = ViewAnimationUtils.createCircularReveal(view,centerX,centerY,startRadius,endRad)
- view 传入你想要实现揭露动画的View
- centerX,centerY 这两个参数组成一个点,是揭露动画圆形的圆心点。
- startRadius 表示圆形的起始半径
- endRadius 表示圆形的结束半径,当到达结束半径的时候,即表示揭露动画结束,不管View有没有完整展示出来,View都会直接全部显示。
2、简单实现
testView.post { //1val width = testView.widthval height = testView.heightval viewHypotenuse = Math.hypot(width.toDouble(), height.toDouble()) //2val anim = ViewAnimationUtils.createCircularReveal(testView,0,0,0f,viewHypotenuse.toFloat())anim.duration = 1000btn_start.setOnClickListener {anim.start()}}
- 为了获取view的宽高,我们在给其post一个代码域。
- 通过宽高,我们得到其斜边的值。
3、小小的优化
当我们用上面的代码实现了揭露动画后,总觉得哪里不对劲~

在最开始的时候,当我们还没有点击按钮执行动画,View就已经显示了~,这时候你再来个揭露动画有嘛意思嘛?就像你媳妇自己把头盖掀了,你觉得不过瘾亲手将头盖盖了回去,然后再自己掀开 ~
所以我们做一些小小的调整:
//1.手动将 View 变成 View.INVISIBLE 不可见的状态//或者在XML中设置testView.visibility = View.INVISIBLEtestView.post {val width = testView.widthval height = testView.heightval viewHypotenuse = Math.hypot(width.toDouble(), height.toDouble())val anim = ViewAnimationUtils.createCircularReveal(testView,0,0,0f,viewHypotenuse.toFloat())anim.duration = 1000btn_start.setOnClickListener {//2.在动画执行之前,手动将 View 变成 View.VISIBLE 可见的状态testView.visibility = View.VISIBLEanim.start()}}
再来看看一看你亲自掀头盖骨的感觉:

在本例中,注意别设置成了 View.GONE ,否则你就获取不到宽高了~
如果你只是想随便看看效果,无论你传啥值都没关系。
4、简单的看看源码
我们找到ViewAnimationUtils类,是个很寒酸的家伙~
只有两个方法,一个是私有构造函数,另一个就是上面用到的createCircularReveal():
public static Animator createCircularReveal(View view,int centerX, int centerY, float startRadius, float endRadius) {return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);}
这个方法也很寒酸~直接返回RevealAnimator,再看看返回值,是Animator,看到这里基本上就知道揭露动画是个什么原理了,搞半天原来你就是官方提供封装的属性动画啊!
另外这个RevealAnimator类被官方@hide了,无法查看,有兴趣的小伙伴自己去看看源码吧。
三、结合Activity
揭露动画还能够和Activity相结合,先看看效果图:

实现的效果如图所示,根据手指点击的地方,展开圆显示跳转的Activity,当Activity返回的时候,又缩回去~
注意要点:是在被打开的Activity中实现揭露动画
1、获取手指点击的位置并打开Activity
因为动画是在第二个Activity中执行的,所以我们得先把圆心位置的参数 x 和 y 传过去。
我是在 Fragmnet 进行的操作,所以是拿到rootView来进行onTouch的监听,如果你是Activity中,可以重写其 onTouchEvent() 方法,来替换下面的 rootView!!.setOnTouchListener
val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {override fun onDown(e: MotionEvent?): Boolean = trueoverride fun onSingleTapUp(e: MotionEvent): Boolean {val x = e.rawXval y = e.rawYval intent = Intent(context,Anim2Activity::class.java)intent.putExtra("x",x)intent.putExtra("y",y)context!!.startActivity(intent)return true}})rootView!!.setOnTouchListener { v, event ->return@setOnTouchListener gestureDetector.onTouchEvent(event)}
2、第二个Activity的代码
class Anim2Activity : AppCompatActivity() {//屏幕的 x 和 y ,以及屏幕斜边private var x = 0private var y = 0private var viewHypotenuse = 0.0f//根 Viewprivate lateinit var rootView:Viewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_anim2)//初始化一些值x = intent.getFloatExtra("x",0f).toInt()y = intent.getFloatExtra("y",0f).toInt()val screenPoint = Point()windowManager.defaultDisplay.getSize(screenPoint)viewHypotenuse = Math.hypot(screenPoint.x.toDouble(), screenPoint.y.toDouble()).toFloat()rootView = findViewById<View>(R.id.rootView)//先将rootView 变为 不可见rootView.visibility = View.INVISIBLErootView.post {val anim = createCircleAnimator(0f,viewHypotenuse)rootView.visibility = View.VISIBLEanim.start()}}/*** 创建揭露动画* @param startRadius 起始半径* @param endRadius 结束半径* @return 返回一个揭露动画*/private fun createCircleAnimator(startRadius:Float,endRadius:Float): Animator {val anim = ViewAnimationUtils.createCircularReveal(rootView,x,y,startRadius,endRadius)anim.duration = 1000return anim}/*** 重写 finish() */override fun finish() {val anim = createCircleAnimator(viewHypotenuse,0f)anim.start()anim.addListener(onEnd = {//监听动画结束的时候,再调用 finish 以关闭 ActivityrootView.visibility = View.INVISIBLEsuper.finish()})}
}
3、优化
当你直接运行的时候,你会发现,和想象的不一样……
为什么你的Activity会有跳转动画?为什么你的Activity背景是白的?
所以我们还要对这个Activity进行一些设置,把他的跳转动画变消失!把他的背景变成透明!
所以我们需要自定义一个style:
<style name="AppTheme.NoAnimation" parent="AppTheme">- "android:windowAnimationStyle"
>@null- "android:windowIsTranslucent">true
- "android:windowBackground">@android:color/transparent
style>
然后设置Activity的theme:
<activity android:name=".module.anim.Anim2Activity"android:theme="@style/AppTheme.NoAnimation"></activity>
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
