Material Design设计语言动画篇共推出六种类型的动画效果:

1、Touch feedback(触摸反馈)

2、Reveal effect(揭露效果)

3、Activity transitions(Activity转换效果)

4、Curved motion(曲线运动)

5、View state changes (视图状态改变)

6、Animate Vector Drawables(矢量动画)

触摸反馈

在Android 5.0以上,当我们设置了Material Design主题后,系统默认就有这种效果了,就是常说的水波纹效果,当触摸可点击的控件时,水波纹就会从触点慢慢的扩散开,如:



这种效果并不需要我们自己设置,默认就是上图那种效果,不过我们也可以控制它的效果,用:

android:background=”?android:attr/selectableItemBackground” - 设置控件背景颜色透明且波纹有边界

android:background=”?android:attr/selectableItemBackgroundBorderless” - 设置控件背景颜色透明且波纹无边界,将会显示一个圆,直径为控件的长度

我把三个按钮分别不加这个属性,加selectableItemBackground属性,加selectableItemBackgroundBorderless属性,看看效果:

<Button
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:background="?attr/selectableItemBackground"
        android:text="Button" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:text="Button" />

效果:



可以看到加了这个属性的背景都透明了,无边界时候显示触摸反馈的是一个圆形

当然,我们可以通过设置style文件来设置Button的默认颜色和触摸水波纹颜色:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorControlHighlight">#673AB7</item>
        <item name="colorButtonNormal">#CDDC39</item>
</style>
//或
<style name="AppTheme" parent="android:Theme.Material.Light">
        <item name="android:colorControlHighlight">#673AB7</item>
        <item name="android:colorButtonNormal">#CDDC39</item>
</style>

这两种都可以,因为Theme.AppCompat是Material Design的兼容包,一般在像5.0以下兼容Material Desing风格时候都是使用它,不过使用了它Activity需要继承AppCompatActivity来达到Material design的效果,而且二者不能同时使用,比如不能使用了Theme.Material.Light的主题再让Activity继承AppCompatActivity,否则将报错。具体Material Design如何向下兼容请看我的这篇文章使用Material Design应用主题

揭露效果

关于这个动画,现在比较流行的就是Activity的揭露出现效果,就是打开一个新的Activity或者UI时,Activity界面会从点击的那个点以波纹形式扩散而成,效果比较炫酷,其实就是用这个揭露动画做的,好了,让我们来看看怎么实现这个动画吧,其实就是通过ViewAnimationUtils工具类创建一个圆形的揭露动画对象,然后设置Animator对象的一些属性值。

Animator mAnimator = ViewAnimationUtils.createCircularReveal(View view,
            int centerX,  int centerY, float startRadius, float endRadius)

view - 需要显示揭露动画的View

centerX - 动画开始的X轴坐标

centerY - 动画开始的Y轴坐标

startRadius - 动画开始时的半径

endRadius - 动画结束时的半径

我们知道了以上的参数意思那么接下来可以设置下看看效果:

布局文件中有两个Button:

<Button
        android:id="@+id/button4"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="New Button" />

    <Button
        android:id="@+id/button5"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="Button" />

分别对这两个Button设置监听器,当点击时候显示动画:

mButton4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animator mAnimator = ViewAnimationUtils.createCircularReveal(mButton4, mButton4.getWidth()/2, mButton4.getHeight()/2, 0, mButton4.getHeight());
                mAnimator.setDuration(2000);
                mAnimator.setInterpolator(new AccelerateInterpolator());
                mAnimator.start();
            }
        });
        mButton5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                float endRadius = (float) Math.hypot(mButton5.getWidth(),mButton5.getHeight());//勾股定理得到斜边长度
                Animator mAnimator = ViewAnimationUtils.createCircularReveal(mButton5, mButton5.getWidth(), 0, 0, endRadius);
                mAnimator.setDuration(2000);
                mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                mAnimator.start();
            }
        });

来看看效果:

如上,效果是慢慢的揭露出来的,这个效果用在一些视图显示的场合、或者视图消失的场合比较酷吧,而且揭露动画也是可以设置插值器和一些其它属性的。

转换效果

转换动画主要就是通过ActivityOptions这个类实现的,只支持api21以上的版本,不过这个类只支持Api21以上的版本,好在Google也在v4包中添加了一个向下兼容类:ActivityOptionsCompat,使用它可以在api21以下的系统上运行,但是没有动画效果,在api21以上的系统上运行就有动画效果,这个兼容类可以帮助我们省去了对系统版本的判断,所以我用它来讲解转换动画

转换动画其实可以分为两类:共享元素转换和普通转换。

要使用转换动画,我们首先需要设置这个Activity让它允许使用转换动画,通过getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);表示允许使用转换动画,设置方式有两种,可以在Activity中用代码设置:

protected void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.laytout_image);
    }

也可以在style.xml中设置:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowContentTransitions">true</item>
</style>

共享元素转换动画

共享元素转换,顾名思义:就是可以把两个Activity中相同元素联系起来作出变换的动画,使用它的前提就是两个Activity有相同的元素,何为元素,即有相同的图片、文本内容、视图等都是元素。那么怎么用呢?

就是通过ActivityOptions创建一个场景转换动画,然后把这个动画传入startActivity()中:

/**
*@activity - 当前的activity
*@sharedElement - 共享的元素视图
*@sharedElementName - 共享元素的名称
*/
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,
            View sharedElement, String sharedElementName)
startActivity(intent, options.toBundle());

这里需要我们传入三个参数,第一个就不说了,第二个就是共享的元素视图,第三个是共享元素的名称,那么怎么获取这两个参数呢?

假如这个界面上有一个ImageView,而另外一个界面上也有一个ImageView,而且这两个ImageView控件的图片都一样,这时候我们可以给这两个ImageView控件的android:transitionName=""(共享元素名称)设置一个相同的名称,名称任意取,所以ImageView就是共享元素了,那么上面的第二个参数当然是传入ImageView了,第三个参数则是传入ImageView的共享元素名称。

所以,我们来实现一个看看:

Activity1:

<ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/two"
        android:transitionName="sunzxyong" />

Activity2:

 <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:scaleType="centerCrop"
        android:src="@mipmap/two"
        android:transitionName="sunzxyong" />

设置好了布局后,然后跳转界面那里的代码:

ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, mImageView, "sunzxyong");
        Intent intent = new Intent(this, ImageDetailActivity.class);
        startActivity(intent, options.toBundle());

运行一下看看效果:





这样,就实现共享元素动画了,可以看到Activity在切换到第二个界面时是用共享元素来做一些平滑动画效果,在第二个界面返回时候共享元素做一些平滑动画效果返回到第一个界面中,【注意】:当第二个Activity结束时并回退这个动画需要调用finishAfterTransition();而不是finish(),所以在第二个Activity中退出时或返回时(onBackPressed)加入finishAfterTransition();即可,表示当前Activity结束前需要做完这个动画。

如何共享多个元素?假如这两个界面上有多个元素一样,那么共享多个元素可以使用Pair.create()的方法,ActivityOptionsCompat.makeSceneTransitionAnimation还有一个重载方法,为:

/**
*@sharedElements - 可变参数,View表示共享元素视图,String表示共享元素名称
*/
ActivityOptionsCompat.makeSceneTransitionAnimation(Activity activity,
            Pair<View, String>... sharedElements)

所以多个共享元素可以这个写:

ActivityOptionsCompat.makeSceneTransitionAnimation(this,Pair.create((View)mImageView, "sunzxyong"), Pair.create((View)mImageView2, "sunzxyong2"));

ActivityOptionsCompat.makeScaleUpAnimation扩张动画

这个动画也是ActivityOptionsCompat类的一个动画效果,它可以指定一个坐标点,然后显示界面时Activity是从这个坐标点往外扩展的,所以在这里顺便讲一下,先来看看它的参数意思:

/**
*@source - The View that the new activity is animating from,界面是从哪个视图上开始扩张
*@startX - 开始扩张的x坐标
*@startY - 开始扩张的y坐标
*@startWidth - 扩张完后Activity的宽度(为0表示全屏)
*@startHeight - 扩张完后Activity的高度(为0表示全屏)
*/
ActivityOptionsCompat makeScaleUpAnimation(View source,
            int startX, int startY, int startWidth, int startHeight)

我们根据上述定义这样一个动画,让Activity从图片的中心点开始扩张至全屏,如:

ActivityOptionsCompat options = ActivityOptionsCompat.makeScaleUpAnimation(mImageView,mImageView.getWidth()/2,mImageView.getHeight()/2,0,0);
        Intent intent = new Intent(this, ImageDetailActivity.class);
        startActivity(intent, options.toBundle());

效果为:



可以看见新的Activity是从图片中心扩张而成的

普通转换效果

普通转换效果有三种:

  • Slide - 滑动效果(默认是从底部往上滑入)
  • Explode - 展开效果
  • Fade - 渐显渐隐效果

它是通过Window.setEnterTransition()和Window.setExitTransition()来控制Activity的进入和退出的转换动画的,所以,使用它我们需要通过getWindow().setEnterTransition(Transition transition);设置,该参数传入的是一个Transition对象,默认的有Slide、Explode和Fade这三种效果,所以,一个标准的设置普通转换效果的代码为:

1、首先要设置该Activity允许使用转换动画

2、然后设置Activity进入和退出的转换动画

3、最后跳转界面时用默认的转换动画ActivityOptionsCompat.makeSceneTransitionAnimation(this);跳转界面,【注】:在有元素共享动画时需要传入其它共享参数,否则,则为普通的转换动画效果

标准的使用代码为:

 protected void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.laytout_image);
        getWindow().setEnterTransition(new Slide());
        getWindow().setExitTransition(new Slide());
        //...
    }
    public void click(View view) {
        ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
        Intent intent = new Intent(this, ***.class);
        startActivity(intent,options.toBundle());
    }

上面在使用getWindow().setEnterTransition(new Slide());传入的是一个Slide对象,其实可以通过它来设置其它的一些参数,比如改变滑入的方向和添加插值器:

Slide mSlide = new Slide();
mSlide.setInterpolator(new AccelerateInterpolator());
mSlide.setSlideEdge(Gravity.TOP);
getWindow().setEnterTransition(mSlide);

其它一些动画效果也是如此设置。

下面通过一个实例来看看具体对应的动画效果是怎么实现的。

先来看看慢动画效果,为了使效果更加明显,我这里设置了动画持续时间为2s,如:



再来看看没有时间delay的默认效果:



贴下主要代码吧!

跳转界面代码:

public void onItemClick(View view, int position) {
        switch (position) {
            case 2:
                Slide mSlide = new Slide();
                mSlide.setDuration(2000);

                getWindow().setExitTransition(mSlide);
                getWindow().setEnterTransition(mSlide);

                ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(RecyclerViewActivity.this);
                Intent intent = new Intent(RecyclerViewActivity.this, SlideActivity.class);
                startActivity(intent, optionsCompat.toBundle());
                break;
            case 3:
                Explode mExplode = new Explode();
                mExplode.setDuration(2000);

                getWindow().setExitTransition(mExplode);
                getWindow().setEnterTransition(mExplode);

                ActivityOptionsCompat optionsCompat2 = ActivityOptionsCompat.makeSceneTransitionAnimation(RecyclerViewActivity.this);
                Intent intent2 = new Intent(RecyclerViewActivity.this, ExplodeActivity.class);
                startActivity(intent2, optionsCompat2.toBundle());
                break;
            case 4:
                Fade mFade = new Fade();
                mFade.setDuration(2000);

                getWindow().setExitTransition(mFade);
                getWindow().setEnterTransition(mFade);

                ActivityOptionsCompat optionsCompat3 = ActivityOptionsCompat.makeSceneTransitionAnimation(RecyclerViewActivity.this);
                Intent intent3 = new Intent(RecyclerViewActivity.this, FadeActivity.class);
                startActivity(intent3, optionsCompat3.toBundle());
                break;
        }
    }

每个动画跳转至的界面,这里我贴一个,其它都是类似:

protected void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fade);
        Fade mFade = new Fade();
        mFade.setDuration(2000);
        getWindow().setExitTransition(mFade);
        getWindow().setEnterTransition(mFade);

        TextView mTextView = (TextView) findViewById(R.id.textView);
        mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finishAfterTransition();
            }
        });
    }

当然这三种动画还可以设置插值器和Mode(mSlide.setMode()),从而达到不同效果的实现。

【总结】:综上所述, 使用转换动画时候最主要是先让这个Activity得到使用转换动画的权利,然后再用ActivityOptionsCompat.makeSceneTransitionAnimation(...)得到ActivityOptionsCompat对象并设置给startActivity(),这样就实现了转换动画。

【注】Material Design的动画只适用与5.0以上的版本才有效果

Demo下载

下一篇讲解剩余的三种类型动画。

Material Design5.x动画实现解析篇一的更多相关文章

  1. Android属性动画完全解析(下)

    转载:http://blog.csdn.net/guolin_blog/article/details/44171115 大家好,欢迎继续回到Android属性动画完全解析.在上一篇文章当中我们学习了 ...

  2. Android属性动画完全解析(上),初识属性动画的基本用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系 ...

  3. Android属性动画完全解析(中)

    转载:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是 ...

  4. Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/44171115 大家好,欢迎继续回到Android属性动画完全解析.在上一篇文章当中 ...

  5. Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法 ...

  6. 基于Rebound制造绚丽的动画效果-入门篇

    基于Rebound制造绚丽的动画效果-入门篇 Rebound是什么? Rebound是一个来自 Facebook 公司的 Java物理和动画库.Rebound spring 模型可用于创建动画,让你感 ...

  7. iOS 动画基础总结篇

    iOS 动画基础总结篇   动画的大体分类(个人总结可能有误) 分类.png UIView 动画 属性动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 ...

  8. php-fpm.conf详细解析篇

    一:php-fpm.conf详细解析篇: pm = static (静态模式)时只需修改 max_children数值 pm = dynamic (动态模式)时只需修改其它三个数值 pm.max_ch ...

  9. mybatis 源码赏析(一)sql解析篇

    本系列主要分为三部分,前两部分主要分析mybatis的实现原理,最后一部分结合spring,来看看mybtais是如何与spring结合的就是就是mybatis-spring的源码. 相较于sprin ...

随机推荐

  1. Cocos2D-ObjC:在RPG游戏中混合Swift代码

    我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>> 编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swi ...

  2. 最大熵模型The Maximum Entropy

    http://blog.csdn.net/pipisorry/article/details/52789149 最大熵模型相关的基础知识 [概率论:基本概念CDF.PDF] [信息论:熵与互信息] [ ...

  3. SQL Server 索引维护(1)——系统常见的索引问题

    前言: 在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次D ...

  4. JAVA对象及属性的内存堆栈管理(通过小程序简单说明)

    JAVA在执行过程中会划分4个内存区域(heap.stack.data segment.code segment)代码区(codesegment):java开始执行会把代码加载到code segmen ...

  5. 剑指offer面试题5 从头到尾打印链表(c)

  6. Android实现分享图片和文字的功能

    为了应用的推广,我们经常看到点击分享按钮会出现,比如微博微信等应用的分享二等列表,这是如何实现的呢?这一篇将要详细的介绍. android的实现分享是通过隐式的启动activity. 分享文本 1.a ...

  7. Dynamics CRM 通过RetrieveEntityRibbonRequest和RetrieveApplicationRibbonRequest导出实体的Ribbon XML

    今天看到勇哥的博客介绍了两个request指令用来导出实体的Ribbon XML,在没有工具之前编辑ribbon都是手工导出xml然后编辑的对于很多一开始接触CRM就用工具的人可能不是很熟悉.查了下这 ...

  8. Java并发框架——AQS阻塞队列管理(二)——自旋锁优化

    看Craig, Landin, and Hagersten发明的CLH锁如何优化同步带来的花销,其核心思想是:通过一定手段将所有线程对某一共享变量轮询竞争转化为一个线程队列且队列中的线程各自轮询自己的 ...

  9. VS2010 express中改变VC Default include/lib/… 目录

    转自: Liz's Blog http://www.cnblogs.com/lizmy/archive/2012/01/10/2318258.html 2010中是以工程为单位,更改VC++ dire ...

  10. THE SCHOOLS WHERE APPLE, GOOGLE, AND FACEBOOK GET THEIR RECRUITS