用最简单的方式来实现Android视图扩散切换效果。

一、概述

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

二、实现思路简单阐述

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

 protected Rect getRectInWindow(View view, boolean mIsFullWindow){
            int[] location = new int[2];
            view.getLocationInWindow(location);
            return new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight());
    }

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

            canvas.save();
            Matrix matrix = new Matrix();
            matrix.postTranslate(mRect.left ,mRect.top);
            matrix.postScale(mScaleXCanvas,mScaleYCanvas,mRect.centerX(),mRect.centerY());
            matrix.postRotate(mRotationCanvas,mRect.centerX(),mRect.centerY());

            canvas.concat(matrix);
            mView.draw(canvas);
            canvas.restore();

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

        mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        setLayerType(LAYER_TYPE_SOFTWARE,null);

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

三、具体使用

 helper = new BaseViewHelper
                .Builder(SecondActivity.this)
                //.setEndView()//如果是两个切换的视图  这里设定最终显示的视图
                .setTranslationView(v)//设置过渡视图
                .isFullWindow(true)//是否全屏显示
                .isShowTransition(true)//是否显示过渡动画
                .setDimColor(Color.WHITE)//遮罩颜色
                .setDimAlpha(200)//遮罩透明度
                //.setTranslationX(0)//x轴平移
                //.setRotation(360)//旋转
                //.setScaleX(0)//x轴缩放
                //.setScaleY(0)//y轴缩放
                //.setTranslationY(0)//y轴平移
                //.setDuration(800)//过渡时长
                //.setInterpolator(new AccelerateDecelerateInterpolator())//设置插值器
                //设置监听
//                .setOnAnimationListener(new BaseViewHelper.OnAnimationListener() {
//                    @Override
//                    public void onAnimationStartIn() {
//                        Log.e("TAG","onAnimationStartIn");
//                    }
//
//                    @Override
//                    public void onAnimationEndIn() {
//                        Log.e("TAG","onAnimationEndIn");
//                    }
//
//                    @Override
//                    public void onAnimationStartOut() {
//                        Log.e("TAG","onAnimationStartOut");
//                    }
//
//                    @Override
//                    public void onAnimationEndOut() {
//                        Log.e("TAG","onAnimationEndOut");
//                    }
//                })
                .create();//开始动画

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

 new BaseViewHelper
                .Builder(MainActivity.this, view)
                .startActivity(intent);

B页面代码:

helper = new BaseViewHelper
                .Builder(SecondActivity.this)
                .isFullWindow(true)//是否全屏显示
                .isShowTransition(true)//是否显示过渡动画
                .setDimColor(Color.WHITE)//遮罩颜色
                .setDimAlpha(200)//遮罩透明度
                .create();//开始动画

    @Override
    public void onBackPressed() {
        if (helper!=null && helper.isShowing()){
            helper.backActivity(this);
        }else {
            super.onBackPressed();
        }
    }

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

在当前页面代码:

            View v = View.inflate(this,R.layout.layout_second,null);
            //显示在当前页面跳转
            helper = new BaseViewHelper.Builder(this,view)
                    .setEndView(v)
                    .create();

    @Override
    public void onBackPressed() {
        if (helper!=null && helper.isShowing()){
            helper.back();
        }else {
            super.onBackPressed();
        }
    }

四、源码地址

项目地址:https://github.com/zhangke3016/ViewSpreadTranslationController

如果喜欢,欢迎star、fork、issues。

两行代码搞定Android视图扩散切换效果的更多相关文章

  1. jquery侧边折叠导航栏制作,两行代码搞定

    jquery侧边折叠导航栏制作,两行代码搞定 //CSS*{margin: 0;padding: 0} ul{list-style: none} .menu li ul{display: none} ...

  2. 两行代码搞定网站gzip压缩

    网站使用gzip压缩的好处就不用多说了吧,自行脑补,来说一下如何使用nodejs实现gzip压缩,只需要两行代码,so ease. 通过nodejs实现gzip 需要用到的模块 compression ...

  3. AJ学IOS(41)UI之核心动画 两行代码搞定3D转场

    AJ分享,必须精品 效果: 代码: 其实代码很少,苹果都给封装好了 // 1.创建核心动画 CATransition *ca = [CATransition animation]; // 1.1动画过 ...

  4. 两行代码搞定 JavaScript 的日期验证

    我们通常在 JavaScript 中验证日期,基本的思路大概是,先判断年月日是否有效,再判断当月是否有当日,比如一些月份没有 31 日,平年二月没有 29.30 日,闰年二月没有 30 日等等. 偶然 ...

  5. BaseHttpListActivity,几行代码搞定Android Http列表请求、加载和缓存

    Android开发中,向服务器请求一个列表并显示是非常常见的需求,但实现起来比较麻烦,代码繁杂. 随着应用的更新迭代,这种需求越来越多,我渐渐发现了实现这种需求的代码的共同点. 于是我将Activit ...

  6. 两行代码搞定UITableView无数据无网络显示-b

    不知是否有像我一样的,每次写TableView在监听网络和无数据源时逻辑处理提示视图都是一堆代码,很繁琐也很重复的垃圾代码(可能就只有我这样

  7. 两行代码搞定js对象深浅拷贝

    有一段时间没有更新博客了,忙于工作.2018年刚过去,今天来开启2018第一篇博文.好了,咱们步入正题. 先上代码 /** * 遍历对象 * 1.判断是不是原始值 * 2.判断是数组还是对象 * 3. ...

  8. 两行代码搞定UI主流框架

    XCNavTab XCNavTab适用于快速搭建NavigationController和TabBarController相结合的框架 https://github.com/xiaocaiabc/XC ...

  9. Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

    原文:Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Android开发 ...

随机推荐

  1. 机器学习:scipy和sklearn中普通最小二乘法与多项式回归的使用对

    相关内容连接: 机器学习:Python中如何使用最小二乘法(以下简称文一) 机器学习:形如抛物线的散点图在python和R中的非线性回归拟合方法(以下简称文二) 有些内容已经在上面两篇博文中提到了,所 ...

  2. postman学习笔记(一)——最简单的postman入门

    昨天开始正式接触postman的操作,最简单的操作是根据接口文档一个个测试接口. 例如: 测试环境地址:http://111.2.198.4(项目组自己的测试环境,要测试的项目组肯定会给你的) //以 ...

  3. SpringIOC学习二

    Spring的IOC容器通过依赖注入DI(dependency injection)来实现程序之间的依赖关系,达到解耦的方式依赖的方式:a.基于xml文件配置的注入    * 构造函数注入    * ...

  4. Java操作属性文件与国际化

    在前面讲到的java类集中的Hashtable中,有一个子类Properties,此类定义如下: public class Properties extends Hashtable<Object ...

  5. [HAOI 2009]逆序对数列

    Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的 数列,可以很容易求出有多少个逆序对数.那么逆 ...

  6. 洛谷P2050 [NOI2012]美食节

    动态加边网络流 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...

  7. [Codeforces]862F - Mahmoud and Ehab and the final stage

    题目大意:n个字符串,支持修改一个位置上的字符串和查询一个区间的子区间中长度乘LCP的最大值,输入字符数和询问数不超过10^5. 做法:求出相邻的LCP长度,区间LCP等于区间最小值,查询分几种情况考 ...

  8. bzoj 3191: [JLOI2013]卡牌游戏

    Description N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X ...

  9. 计蒜客NOIP2017提高组模拟赛(三)day2-直线的交点

    传送门 简单几何+逆序对 发现当两条直线甲乙与平板的交点在上面甲在较左的位置,那么下面甲在较右的位置就可以相交 然后把上面的位置排下序,下面离散化+树状数组即可 #include<cstdio& ...

  10. 【BZOJ3631】【JLOI2014】松鼠的新家

    原题传送门 题意:给你一棵树,然后有一个遍历顺序,你需要补全这个遍历顺序,然后输出这个遍历顺序中每个点的出现次数. 解题思路:本来想找树剖的题,结果发现了一题可以直接写lca的.... 做法1:非常简 ...