Android 创建CircularReveal揭露动画的实现
来源:互联网 发布:影响因素分析模型知乎 编辑:程序博客网 时间:2024/05/20 17:40
在Android 5.0及更高的版本中,加入了一种全新的视觉动画效果,就是揭露动画。揭露动画在系统中很常见,就是类似波纹的效果,从某一个点向四周展开或者从四周向某一点聚合起来,本文实现的效果如下所示,可以用在Activity里面的View动画效果,也可以使用在Activity跳转过渡动画中:
使用揭露动画非常简单,Android Sdk中已经帮我们提供了一个工具类ViewAnimationUtils来创建揭露动画。ViewAnimationUtils里面只有两个静态方法createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius),返回一个Animator动画对象。
public final class ViewAnimationUtils {
private ViewAnimationUtils() {}
/**
* Returns an Animator which can animate a clipping circle.
*
* Any shadow cast by the View will respect the circular clip from this animator.
*
* Only a single non-rectangular clip can be applied on a View at any time.
* Views clipped by a circular reveal animation take priority over
* {@link View#setClipToOutline(boolean) View Outline clipping}.
*
* Note that the animation returned here is a one-shot animation. It cannot
* be re-used, and once started it cannot be paused or resumed. It is also
* an asynchronous animation that automatically runs off of the UI thread.
* As a result {@link AnimatorListener#onAnimationEnd(Animator)}
* will occur after the animation has ended, but it may be delayed depending
* on thread responsiveness.
*
* Note that if any start delay is set on the reveal animator, the start radius
* will not be applied to the reveal circle until the start delay has passed.
* If it’s desired to set a start radius on the reveal circle during the start
* delay, one workaround could be adding an animator with the same start and
* end radius. For example:
* public static Animator createRevealWithDelay(View view, int centerX, int centerY, float startRadius, float endRadius) {
* Animator delayAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, startRadius);
* delayAnimator.setDuration(delayTimeMS);
* Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view, centerX, centerY, startRadius, endRadius);
* AnimatorSet set = new AnimatorSet();
* set.playSequentially(delayAnimator, revealAnimator);
* return set;
* }
*
* @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
*view
.
* @param centerY The y coordinate of the center of the animating circle, relative to
*view
.
* @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() 方法能够为裁剪区域添加动画以揭露或隐藏视图。我们主要使用createCircularReveal 方法,该方法有四个参数,第一个参数是执行揭露动画的View视图,第二个参数是相对于视图View的坐标系,动画圆的中心的x坐标,第三个参数是相对于视图View的坐标系,动画圆的中心的y坐标,第四个参数是动画圆的起始半径,第五个参数动画圆的结束半径。如下图所示:
揭露动画有两种效果,一种是显示一组UI元素,另一种是隐藏一组UI元素:
注意:揭露动画对象只能使用一次,不能被重新使用,也就是说每次使用揭露动画都要调用ViewAnimationUtils.createCircularReveal()返回一个揭露动画对象使用,同时一旦开始了动画就不能暂停或重新开始。揭露动画是一种异步动画,可以自动运行在UI线程上。当揭露动画结束后,如果设置了Animator.AnimatorListener监听器,那么监听器的onAnimationEnd(Animator) 方法会被调用,但可能会被延迟调用,这取决于线程的响应能力。
首先我们可以创建一个工具类:
val Duration:Long=1000class CircularRevealUtil { var animationListener: CircularRevealAnimationListener? = null interface CircularRevealAnimationListener{ fun onShowAnimationEnd() fun onHideAnimationEnd() } fun setCircularRevealAnimationListener(animationListener: CircularRevealAnimationListener){ this.animationListener=animationListener } fun showTargetView(view: View){ val centerX:Int=(view.left+view.right)/2 val centerY:Int=(view.top+view.bottom)/2 val finalRadius:Float=Math.max(view.width,view.height).toFloat() val anim: Animator = ViewAnimationUtils.createCircularReveal(view,centerX,centerY,0f,finalRadius) anim.duration=Duration view.clearAnimation() anim.addListener(object : AnimatorListenerAdapter(){ override fun onAnimationStart(animation: Animator?) { super.onAnimationStart(animation) view.visibility= View.VISIBLE } override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) if(animationListener!=null){ animationListener!!.onShowAnimationEnd()//!!断言 当为空会抛出异常 } } }) anim.start() } fun hideTargetView(view: View){ val centerX:Int=(view.left+view.right)/2 val centerY:Int=(view.top+view.bottom)/2 val initRadius:Float=Math.max(view.width,view.height).toFloat() val anim: Animator = ViewAnimationUtils.createCircularReveal(view,centerX,centerY,initRadius,0f) anim.duration=Duration view.clearAnimation() anim.addListener(object: AnimatorListenerAdapter(){ override fun onAnimationEnd(animation: Animator?) { super.onAnimationEnd(animation) view.visibility= View.GONE if(animationListener!=null){ animationListener!!.onHideAnimationEnd() } } }) anim.start() }}
CircularRevealAnimationListener接口是用户回调接口,当用户设置了接口回调时就会在揭露显示动画或揭露隐藏动画结束时收到通知从而进行操作。showTargetView方法是从隐藏到完全显示一个View,hideTargetView方法是从一个完全显示的View到隐藏。
然后就可以在MainActivity中显示或隐藏一组View或者做跳转动画了。
当需要经揭露动画作为跳转Activity动画时,需要设置下系统的默认动画效果。首先需要在styles.xml文件中设置主题,将window窗口的默认跳转动画关闭,将window背景设置为透明,如下所示:
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:textAllCaps">false</item> <item name="android:windowAnimationStyle">@null</item>//设置跳转动画为null,即没有动画 <item name="android:windowBackground">@android:color/transparent</item>//设置窗口背景为透明 <!--<item name="android:colorBackgroundCacheHint">@null</item>--> <item name="android:windowIsTranslucent">true</item>//设置窗口为透明 </style></resources>
在MainActivity中:
class MainActivity : BaseActivity() { lateinit var imageView:ImageView lateinit var button:Button lateinit var rootView:ConstraintLayout lateinit var toSecondAct:Button lateinit var circularRevealAnim:CircularRevealUtil var isShow:Boolean=true override fun setView() { setContentView(R.layout.activity_main) imageView= findViewById(R.id.ImageView) as ImageView button= findViewById(R.id.Button) as Button rootView= findViewById(R.id.RootView) as ConstraintLayout toSecondAct= findViewById(R.id.ToSecondAct) as Button } override fun setData() { circularRevealAnim= CircularRevealUtil() } override fun setListener() { button.setOnClickListener{_-> if(isShow){ isShow=false button.text="showImage" circularRevealAnim.hideTargetView(imageView) }else{ isShow=true button.text="hideImage" circularRevealAnim.showTargetView(imageView) } } toSecondAct.setOnClickListener{_-> val intent=Intent(this,SecondActivity::class.java) startActivity(intent) } }}
在SecondActivity中:
class SecondActivity:BaseActivity(){ lateinit var button:Button lateinit var imageView:ImageView lateinit var circularRevealAnim:CircularRevealUtil lateinit var rootView:ConstraintLayout override fun setView() { setContentView(R.layout.activity_second) button= findViewById(R.id.Second_Button) as Button imageView= findViewById(R.id.Second_ImageView) as ImageView rootView= findViewById(R.id.Second_RootView) as ConstraintLayout } override fun setData() { circularRevealAnim= CircularRevealUtil() rootView.post { circularRevealAnim.showTargetView(rootView) } } override fun setListener() { button.setOnClickListener{_-> circularRevealAnim.hideTargetView(rootView) } circularRevealAnim.setCircularRevealAnimationListener(object:CircularRevealUtil.CircularRevealAnimationListener{ override fun onHideAnimationEnd() { finish() } override fun onShowAnimationEnd() { } }) }}
- Android 创建CircularReveal揭露动画的实现
- Android CircularReveal揭露动画三种实现
- Android 动画-CircularReveal
- Android 5.0 动画之CircularReveal
- Android Material Design(6) CircularReveal圆形扩散动画的使用
- Android Reveal Animation(揭露动画)实现
- Android开发 之 揭露动画
- Android Activity转场 -- 揭露动画
- AndroidMaterialDesign动画之CircularReveal
- Android动画学习(六)之View揭露效果和SurfaceView实现动画
- 一个揭露动画的的折线图
- CircularReveal
- Android 使用Circular Reveal为你的应用添加揭露动画效果
- android仿美团底部导航栏的点击效果——揭露动画
- android开发游记:meterial design 使用circularReveal仿哔哩哔哩(bilibili)搜索框动画
- android开发游记:meterial design 使用circularReveal仿哔哩哔哩(bilibili)搜索框动画
- 使用CircularReveal动画效果切换页面
- 揭露动画ViewAnimationUtils.createCircularReveal()
- lnmp、lamp、lnmpa一键安装包(Updated: 2017-8-13)
- const在C++ 和C 中的比较
- QT QUdpSocket类
- db2笔记
- NYOJ 20 吝啬的国度(深搜)
- Android 创建CircularReveal揭露动画的实现
- ChainMap用法
- 进制转换,运算符,类型转换,
- Python学习笔记(十二)
- android 内存泄露分析
- Activity生命周期(上)
- [DP] 51 Nod 1274——最长递增路径
- SQLserver 记事本
- phpStudy+XDebug配置