开发文章

两行代码搞定Android视图扩散切换效果

一、概述

这两天时间动手撸了个视图扩散切换效果的控制器,API兼容至Android4.0,更方便我们在视图切换过程中有炫酷的过渡效果。本来是想实现两个View之间的过渡动画,实现的过程中想到之前写的Activity切换动画,就试着加上了对Activity切换的动画支持。先来看看效果吧,代码实现只需一行,感觉还不错~

Activity切换的动画.gifActivity切换的动画1.gifActivity切换的动画3.gif

二、实现思路简单阐述

关于过渡动画的实现,我们先简单分解下这个效果,首先,当Activity发生跳转时我们要先获取共享元素控件,在跳转的界面将其添加在跳转页面之上,关于控件位置的获取,在上一篇文章Android碎裂的粒子效果一文中进行了介绍,主要是通过如下方法获取其位置:

复制内容到剪贴板
  1. protected Rect getRectInWindow(View view, boolean mIsFullWindow){  
  2.             int[] location = new int[2];  
  3.             view.getLocationInWindow(location);  
  4.             return new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight());  
  5.     }  

当跳转至目标页面,我们现在其上方盖上一层遮罩,遮罩为我们自定义的控件,在控件上方绘制上一个页面的过渡视图,将其旋转、平移、或者缩放操作:

复制内容到剪贴板
  1. canvas.save();  
  2. Matrix matrix = new Matrix();  
  3. matrix.postTranslate(mRect.left ,mRect.top);  
  4. matrix.postScale(mScaleXCanvas,mScaleYCanvas,mRect.centerX(),mRect.centerY());  
  5. matrix.postRotate(mRotationCanvas,mRect.centerX(),mRect.centerY());  
  6.   
  7. canvas.concat(matrix);  
  8. mView.draw(canvas);  
  9. canvas.restore();  

最后就是圆形散开效果了,这里我在自定义控件上使用的是Xfermode,不断drawCircle并扩大半径,最终显示出跳转页面视图并将遮罩移除。记得关闭硬件加速。

复制内容到剪贴板
  1. mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));  
  2.      setLayerType(LAYER_TYPE_SOFTWARE,null);  

返回动画同理,在界面返回前将遮罩盖在上一个页面之上,遮罩包括当前页面的视图影像,不断drawCircle并缩小其半径,同时减小当前页面视图的透明度,最终平滑的显示出上一个页面并移除遮罩。

三、具体使用

复制内容到剪贴板
  1. helper = new BaseViewHelper  
  2.                 .Builder(SecondActivity.this)  
  3.                 //.setEndView()//如果是两个切换的视图  这里设定最终显示的视图  
  4.                 .setTranslationView(v)//设置过渡视图  
  5.                 .isFullWindow(true)//是否全屏显示  
  6.                 .isShowTransition(true)//是否显示过渡动画  
  7.                 .setDimColor(Color.WHITE)//遮罩颜色  
  8.                 .setDimAlpha(200)//遮罩透明度  
  9.                 //.setTranslationX(0)//x轴平移  
  10.                 //.setRotation(360)//旋转  
  11.                 //.setScaleX(0)//x轴缩放  
  12.                 //.setScaleY(0)//y轴缩放  
  13.                 //.setTranslationY(0)//y轴平移  
  14.                 //.setDuration(800)//过渡时长  
  15.                 //.setInterpolator(new AccelerateDecelerateInterpolator())//设置插值器  
  16.                 //设置监听  
  17. //                .setOnAnimationListener(new BaseViewHelper.OnAnimationListener() {  
  18. //                    @Override  
  19. //                    public void onAnimationStartIn() {  
  20. //                        Log.e("TAG","onAnimationStartIn");  
  21. //                    }  
  22. //  
  23. //                    @Override  
  24. //                    public void onAnimationEndIn() {  
  25. //                        Log.e("TAG","onAnimationEndIn");  
  26. //                    }  
  27. //  
  28. //                    @Override  
  29. //                    public void onAnimationStartOut() {  
  30. //                        Log.e("TAG","onAnimationStartOut");  
  31. //                    }  
  32. //  
  33. //                    @Override  
  34. //                    public void onAnimationEndOut() {  
  35. //                        Log.e("TAG","onAnimationEndOut");  
  36. //                    }  
  37. //                })  
  38.                 .create();//开始动画  

如果从A页面跳转至B页面,也就是Activity之间的跳转时,在A页面如下代码

 

复制内容到剪贴板
  1. new BaseViewHelper  
  2.                 .Builder(MainActivity.this, view)  
  3.                 .startActivity(intent);  

B页面代码

复制内容到剪贴板
  1. helper = new BaseViewHelper  
  2.                 .Builder(SecondActivity.this)  
  3.                 .isFullWindow(true)//是否全屏显示  
  4.                 .isShowTransition(true)//是否显示过渡动画  
  5.                 .setDimColor(Color.WHITE)//遮罩颜色  
  6.                 .setDimAlpha(200)//遮罩透明度  
  7.                 .create();//开始动画  
  8.   
  9.     @Override  
  10.     public void onBackPressed() {  
  11.         if (helper!=null && helper.isShowing()){  
  12.             helper.backActivity(this);  
  13.         }else {  
  14.             super.onBackPressed();  
  15.         }  
  16.     }  

如果在一个页面两个视图之间跳转,即A视图切换到B视图:
在当前页面代码:

复制内容到剪贴板
  1.      View v = View.inflate(this,R.layout.layout_second,null);  
  2.         //显示在当前页面跳转  
  3.         helper = new BaseViewHelper.Builder(this,view)  
  4.                 .setEndView(v)  
  5.                 .create();  
  6.   
  7.   
  8. @Override  
  9. public void onBackPressed() {  
  10.     if (helper!=null && helper.isShowing()){  
  11.         helper.back();  
  12.     }else {  
  13.         super.onBackPressed();  
  14.     }  
  15. }  

四、源码地址

项目地址:https://github.com/zhangke3016/ViewSpreadTranslationController
如果喜欢,欢迎star、fork、issues。


感谢 zhangke3016 支持 磐实编程网 原文地址:
blog.csdn.net/zhangke3016/article/details/54285749

文章信息

发布时间:2017-01-10

作者:zhangke3016

发布者:aquwcw

浏览次数: