Android使用Circular Reveal动画让页面跳转更炫酷
android 5.0中引入了很多炫酷的动画效果,circular reveal便是其中一种。使用起来很简单,但效果却是意想不到的炫酷,让你的app更有逼格。
一、效果
废话不说,下面的gif图中使用circular reveal动画实现跳转到搜索页的效果。gif图压缩宽高比失真了,不过效果还在。源码在最下面,可以下载体验下。
二、circular reveal介绍
当您显示或隐藏一组 ui 元素时,揭露动画可为用户提供视觉连续性。
viewanimationutils.createcircularreveal()方法让您能够为裁剪区域添加动画以揭露或隐藏视图。
/* @param view the view will be clipped to the animating circle. * @param centerx the x coordinate of the center of the animating circle, relative to * <code>view</code>. * @param centery the y coordinate of the center of the animating circle, relative to * <code>view</code>. * @param startradius the starting radius of the animating circle. * @param endradius the ending radius of the animating circle. */ public static animator createcircularreveal(view view, int centerx, int centery, float startradius, float endradius) { return new revealanimator(view, centerx, centery, startradius, endradius); }
viewanimationutils.createcircularreveal()方法所执行的效果,就是将一个view裁剪成圆,然后从圆心逐渐揭露展现视图。
参数 | 参数说明 |
---|---|
view | 要执行动画效果的view |
centerx | 圆心x坐标 |
centery | 圆心y坐标 |
startradius | 开始时的圆半径 |
endradius | 结束时的圆半径 |
三、实现
从上图可以看出,需要揭露展现的view是整个视图的根布局。开始的位置就是????图标的x,y坐标。开始的半径为0,结束的半径是上面那条斜边的长度。知道了这些参数,那么实现就简单了。
以下代码使用kotlin实现,不过和java区别不大,不影响看懂原理。
1.动画参数
@suppresslint("newapi") private fun actionothervisible(isshow: boolean, triggerview: view, animview: view) { //判断api是否大于21 if (android.os.build.version.sdk_int < android.os.build.version_codes.lollipop) { if (isshow) { animview.visibility = view.visible if (mlistener != null) mlistener!!.onshowanimationend() } else { animview.visibility = view.gone if (mlistener != null) mlistener!!.onhideanimationend() } return } /** * 计算 triggerview(即搜索按钮) 的中心位置 */ val tvlocation = intarray(2) triggerview.getlocationinwindow(tvlocation) val tvx = tvlocation[0] + triggerview.width / 2 val tvy = tvlocation[1] + triggerview.height / 2 /** * 计算 animview(即根布局) 的中心位置 */ val avlocation = intarray(2) animview.getlocationinwindow(avlocation) val avx = avlocation[0] + animview.width / 2 val avy = avlocation[1] + animview.height / 2 //计算宽高 val ripplew = if (tvx < avx) animview.width - tvx else tvx - avlocation[0] val rippleh = if (tvy < avy) animview.height - tvy else tvy - avlocation[1] //勾股定理求斜边 val maxradius = math.sqrt((ripplew * ripplew + rippleh * rippleh).todouble()).tofloat() val startradius: float val endradius: float //根据展示或隐藏设置起始与结束的半径 if (isshow) { startradius = 0f endradius = maxradius } else { startradius = maxradius endradius = 0f } val anim = viewanimationutils.createcircularreveal(animview, tvx, tvy, startradius, endradius) animview.visibility = view.visible anim.duration = duration anim.interpolator = decelerateinterpolator() //监听动画结束,进行回调 anim.addlistener(object : animatorlisteneradapter() { override fun onanimationend(animation: animator) { super.onanimationend(animation) if (isshow) { animview.visibility = view.visible if (mlistener != null) mlistener!!.onshowanimationend() } else { animview.visibility = view.gone if (mlistener != null) mlistener!!.onhideanimationend() } } }) anim.start() }
上述代码中注释清楚解析了动画参数的获取和执行过程。
2.动画调用
fun show(triggerview: view, showview: view) { actionothervisible(true, triggerview, showview) } fun hide(triggerview: view, hideview: view) { actionothervisible(false, triggerview, hideview) }
actionothervisible()方法根据传入true/false来确定是执行展示或隐藏动画。
3.动画调用时机
在searchfragment中,监听第一帧的绘制,开启动画。其中mrootview就是根布局view。
override fun onpredraw(): boolean { iv_search_search.viewtreeobserver.removeonpredrawlistener(this); mcircularrevealanim.show(iv_search_search, mrootview); return true; }
动画结束调用时机:①在点击搜索,跳转到搜索结果界面。②物理回退键回退。③点击回退按钮
再以上三个地方都可以调用hide()方法,实现隐藏动画。
4.监听回调
在上面配置动画参数的过程中,对动画结束进行了监听回调。调用了animlistener接口的onhideanimationend()和onshowanimationend()方法,来实现回调。所有在searchfragment中实现该接口,来监听回调。
override fun onhideanimationend() { et_search_keyword.settext(""); dismiss(); } override fun onshowanimationend() { if (isvisible) { keyboardutils.openkeyboard(activity, et_search_keyword); } }
监听到隐藏动画结束的时候,调用dismiss()方法关闭该dialogfragment。监听展现动画结束的时候,开启输入法框。
就是这么简单,通过以上方式就可以实现如此炫酷的效果。
github地址:搜索页circular reveal动画
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。