Android动画最新最全详解包含Material Design动画

以前写动画也是零零种种,需要的时候就查API或找现成的,不够系统。现在通过学习将Android整个动画体系勾勒出来,做到有的放矢。
安卓框架提供了2个动画系统:属性动画(Android 3.0)View动画。这两种动画系统都是可行的,但是,在一般情况下,属性动画是首选的方法,因为它是更灵活,提供更多的功能。除了这两个系统,你可以利用Drawable动画,它允许你一帧一个的加载显示Drawable资源。所以总体来说Android API提供了三类的动画:
- Tween动画或View动画(API 1.0开始)
- Drawable动画或Frame动画、帧动画
- Property动画:Android 3.0(API 11)以上版本可用,Android推荐。

Android有关动画的类在android.view.animation包中,抽象类Animation有很多子类,以完成不同的动画效果。

Animation子类 动画效果
AlphaAnimation 渐变透明度动画效果
RotateAnimation 旋转动画
ScaleAnimation 尺寸缩放动画
TranslateAnimation 位移动画
AnimationSet 动画容器

Tween动画结束时View的布局属性并未发生变化

Animation类中有一个内部动画监听类AnimationListener,通过它主要实现动画开始、进行到结束的事件监听。它有三个方法void onAnimationStart(Animation animation);void onAnimationRepeat(Animation animation);void onAnimationEnd(Animation animation);

在res/anim目录下定义动画文件,然后在代码中AnimationUtilsd.loadAnimation(context,animId)来调用。

Tween动画

View动画或Tween动画在Android比较老的系统中就有了,它仅适用于View。它也比较容易设置,可以提供足够的能力,以满足许多应用的需求。

Animation通用属性:

xml属性 Java代码 说明
android:duration setDuration(long) 动画持续时间,ms为单位
android:fillAfter setFillAfter(boolean) 动画结束时是否保留在最后状态
android:fillBefore setFillBefore(boolean) 动画结束时是否还原到初始状态(默认是true)
android:fillEnabled setFillEnabled(boolean) 同android:fillBefore
android:interpolator setInterpolator 设定插值器。&
android:repeatCount setRepeatCount(int) 设置重复次数
android:repeatMode setRepeatMode() 设置重复模式(reverse
android:startOffset setStartOffset 调用start函数后等待多久后开始
android:zAdjustment setZAdjustment 设置z轴位置(top

& 3种插值器:accelerate_decelerate_interpolator 加速-减速 动画插入器 accelerate_interpolator 加速-动画插入器 decelerate_interpolator减速- 动画插入器

Alpha动画属性:

XML属性 Java代码 说明
android:fromAlpha AlphaAnimation(float fromAlpha, float toAlpha) 动画开始的透明度
android:toAlpha AlphaAnimation(float fromAlpha, float toAlpha) 动画结束时的透明度
<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:fromAlpha="1.0" android:toAlpha="0.1"/>

Rotate动画属性

XML属性 Java代码 说明
android:fromDegrees RotateAnimation(float fromDegrees, …) 旋转开始角度,正表示逆时针
android:toDegrees RotateAnimation(…, float toDegrees) 旋转结束角度,负代表正时针
android:pivotX RotateAnimation(…, …, float pivotX,…) 旋转起点X坐标,*
android:pivotY RotateAnimation(…,…,…, float pivotY) 旋转起点Y坐标
<rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" />

Scale动画属性:

XML属性 Java代码 说明
android:fromXScale ScaleAnimation(float fromX, …) 初始X轴缩放比例 ,1是不变,0是最小,0~1是缩小,>1是放大。
android:toXScale ScaleAnimation(…, float toX,…) 结束X轴缩放比例,同上
android:fromYScale ScaleAnimation(…, float fromY,…) 初始Y轴缩放比例,同上
android:toYScale ScaleAnimation(…, float toY) 结束Y轴缩放比例,同上
android:pivotX ScaleAnimation(…, float pivotX, …) 缩放起点X坐标 *
android:pivotY ScaleAnimation(…, float pivotY) 缩放起点Y坐标 *
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="1.0" android:fromYScale="1.0" android:pivotX="50%" android:pivotY="50%" android:toXScale="0.1" android:toYScale="0.1" />

Translate动画属性

XML属性 Java代码 说明
android:fromXDelta ScaleAnimation(float fromX, …) 初始X轴坐标 *
android:toXDelta ScaleAnimation(…, float toX,…) 结束X轴坐标 *
android:fromYDelta ScaleAnimation(…, float fromY,…) 初始Y轴坐标 *
android:toYDelta ScaleAnimation(…, float toY) 结束Y轴坐标 *
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="20%" android:fromYDelta="20%" android:toXDelta="50%" android:toYDelta="50%" />

*数值或百分数,如50表示View的左上角50个像素为起始点,50%表示以当前View的左上角加上当前View的50%宽高作为起始点,50%p表示以当前View的左上角加父控件的50%的宽高为起始点。在XML中可以方便的用%号来表示,那么在代码中,使用pivotType表示,有三种:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF,和 Animation.RELATIVE_TO_PARENT

Tween动画原理

Tween动画是通过ParentView来不断调整ChildView的画布坐标系来实现的。

applyTransformation(float interpolatedTime, Transformation t)Transformation里面有一个矩阵Matrix,和Alpha。实现自己的动画,也是继承Animation,然后重写applyTransformation方法。
根据这个原理,定制自己的Tween动画:借助android.graphics.Camera类。可实现
- 3D翻转动画
- 扭曲动画
- 抛物线

动画集合AnimationSet

可以通过在XML中定义多个动画,执行时里面的动画是同时执行的。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <alpha/>
  <scale/>
  <translate/>
  <rotate/>
</set>

Drawable动画

Drawable动画,也叫帧动画。它对应的操作类在android.graphics.drawable包下,AnimationDrawable类。有XML方式和Java代码两种方式。

AnimationDrawable逐帧动画

它的属性如下:

属性(方法) 方法
start() 开始播放
stop() 通知播放
addFrame(Drawable frame,int duration) 添加一帧,并设置持续时间
getDuration(int index) 得到指定帧的持续时间
getFrame(int index) 得到指定帧的drawable
getNumberOfFrames() 得到所有帧的数量
isOneShot() 是否执行一次
isRunning() 是否正在播放
setOneShot(boolean oneShot) 设置是否执行一次

注意:start()方法不能再Activity的onCreate()中调用,因为那时AnimationDrawable还未完全附着在Window上。如果想最快的运行,可在onWindowFocusChange()方法中调用。

XML中设置:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
    <item android:drawable="@mipmap/common_loading3_0" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_1" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_2" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_3" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_4" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_5" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_6" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_7" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_8" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_9" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_10" android:duration="50"/>
    <item android:drawable="@mipmap/common_loading3_11" android:duration="50"/>
</animation-list>

Java中设置:

@TargetApi(16)
AnimationDrawable animationDrawable = new AnimationDrawable();
Resources r = getResources();
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_0), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_1), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_2), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_3), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_4), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_5), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_6), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_7), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_8), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_9), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_10), 50);
animationDrawable.addFrame(r.getDrawable(R.mipmap.common_loading4_11), 50);
animationDrawable.setOneShot(false);
if(Build.VERSION.SDK_INT <= 16){
   ivAnimDrawableJava.setBackgroundDrawable(animationDrawable);
}else{
   ivAnimDrawableJava.setBackground(animationDrawable);
}
animationDrawable.start();

AnimatedRotate

另一种AnimtionDrawable,很方便让一个Drawable不停的旋转

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vector_drawable" android:pivotX="50%" android:pivotY="50%" android:visible="true"/>

Interpolator插值器

Interpolator是一个接口,继承TimeInterpolator接口,TimeInterpolator只有一个抽象方法需要实现:float getInterpolation(float input)。Android系统提供了很多内置的一些插值器,比如:
- AccelerateInterpolator:动画从开始到结束,变化率是一个加速的过程。
- DecelerateInterpolator:动画从开始到结束,变化率是一个减速的过程。
- CycleInterpolator:动画从开始到结束,变化率是循环给定次数的正弦曲线。
- AccelerateDecelerateInterpolator:动画从开始到结束,变化率是先加速后减速的过程。
- LinearInterpolator:动画从开始到结束,变化率是线性变化。
LinearInterpolator线形插值器的源码如下:

@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
    }

插补器的原理就是通过改变实际执行动画的时间点,提前/延迟执行默认的时间点来达到加速/减速的效果。在getInterpolation方法中直接返回input(0.0~1.0f)之间的一个值。input表示正常执行动画的时间点,返回值是用户真正想要它执行的时间点,LinearInterpolator返回input,他们的斜率(比值)是个常数,所以表示匀速,速率不变。我们可以通过在里面设置函数改变动画的速率。如加速插值器里的getInterpolation方法是这样实现的:具体分析参考:详解之android动画interpolator插补器。

public float getInterpolation(float input) {
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
}

我们自定义Interpolator也是这样实现,继承BaseInterpolator,实现getInterpolation方法,在getInterpolation方法中实现自己的插值函数,做出想要的动画效果。

Property动画

Android 里的 Property 动画是为了弥补之前 View 动画的不足而在 API 11之后引入系统的。Property 动画功能非常强大和灵活,学好、用好 Property 动画将对 App 开发带来很好的效果。
Property动画本质是修改对象属性值实现的动画。在2.3以前的版本中,可以使用NineOldAndroids框架,实现属性动画。

Property动画和Tween动画的不同:

  • Tween动画只能用于View,Property可以用在任何对象上。
  • Tween动画只是绘制效果动画,View的真正属性没有改变。
  • Tween动画代码量少,使用简单方便。

类体系结构

在android.animation包下,抽象类Animator是所有属性动画的超类。
Android动画最新最全详解包含Material Design动画_第1张图片
有两个重要的类:
- Keyframe:fraction(时间)、value(具体值)、interpolator(插值器)。
- PropertyValueHolder:Property(x位置…)、Keyframe集合。

Property动画属性

Animator

XML属性 Java代码 说明
android:duration setDuration(long duration) 动画时长
android:interpolator setInterpolator(TimeIntepolator v) 插值器
android:startOffset setStartDelay(long delay) 调用start方法后动画延迟时间
setTartget(Object o) 动画对象

ValueAnimator

XML属性 Java代码 说明
android:repeatMode setRepeatMode(int value) 重复模式
android:repeatCount setRepeatCount(int count) 重复次数
android:valueFrom,\nandroid:valueTo,\nandroid:valueType ofArgb(int..),\nofint(int …) ,\nofFloat(float…) float,int或color类型,\nfloat,int或color类型,\nintType或floatType,color不用指定
setFrameDelay(long delay) 多长时间刷新一次

ObejctAnimator

XML属性 Java代码 说明
android:propertyName setPropertyName() String类型,必须要设置的节点属性

注意:动画更新的过程中会不断更新该属性,所以对象比较提供该属性的处理方法(getXXX,setXXX)。
属性:x,y,rotateX,rotateY,traslateX,translateY,alpha,scaleX,scaleY
Property动画的原点在对象父容器的0,0位置

AnimationSet

XML属性 Java代码 说明
android:ordering playSequentially()/playTogether() 子动画是先后有序的还是同时进行。

Property动画使用

XML方式

res/animator目录下定义xml(TimeAnimator不支持),然后使用AnimatorInfaltor.loadAnimator(context,animId)。

res/animator/object_set.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially">

    <!-- set中可以嵌套set,先執行這個set中同時执行的动画 -->
    <set android:ordering="together">
        <objectAnimator  android:duration="1000" android:propertyName="x" android:valueFrom="0" android:valueTo="250" android:valueType="floatType" />
        <objectAnimator  android:duration="1000" android:propertyName="y" android:valueFrom="0" android:valueTo="250" android:valueType="floatType" />

        <objectAnimator  android:duration="1000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" />
        <objectAnimator  android:duration="1000" android:propertyName="rotationX" android:valueFrom="0" android:valueTo="360" />
        <objectAnimator  android:duration="1000" android:propertyName="rotationY" android:valueFrom="0" android:valueTo="360" />
    </set>


    <objectAnimator  android:duration="1000" android:propertyName="scaleX" android:valueFrom="1" android:valueTo="0.5" /><!-- 如果第一次缩小到0.5,第二次再次缩放就没效果,因为属性改了 -->
    <objectAnimator  android:duration="1000" android:propertyName="scaleY" android:valueFrom="1" android:valueTo="0.5" />

    <objectAnimator  android:duration="1000" android:propertyName="alpha" android:valueFrom="1" android:valueTo="0.5" />

</set>

Java方式

对于在XML中定义的动画,在代码中我们这样来使用:

Animator anim0 = AnimatorInflater.loadAnimator(context,R.animator.object_set);
anim0.setTarget(imageView);
anim0.start();

我们也可以自己写ObjectAnimator来实现属性动画:

//如果只写valueTo,则valueFrom表示当前的值
//创建了两个ObjectAnimator,两个动画同时执行
ObjectAnimator.ofFloat(imageView,"rotationX",0f,360f).setDuration(500).start();
ObjectAnimator.ofFloat(imageView,"rotationY",0f,360f).setDuration(500).start();

上面一个ObjectAnimator只修改一个属性,我们还可以让一个ObjectAnimator同时修改多个属性,使用PropertyValuesHolder

//一个动画对多个属性进行修改。PropertyValuesHolder对应某一个属性
PropertyValuesHolder x = PropertyValuesHolder.ofFloat("x",0,250);//里面会生成Keyframe的集合
PropertyValuesHolder y = PropertyValuesHolder.ofFloat("y",0,250);
PropertyValuesHolder sx = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.5f);
PropertyValuesHolder sy = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.5f);
PropertyValuesHolder ry = PropertyValuesHolder.ofFloat("rotationY",0,360);
ObjectAnimator.ofPropertyValuesHolder(imageView,x,y,sx,sy,ry).setDuration(3000).start();

我们还可以对其中的关键帧进行设置,比如:

//一个PropertyValuesHolder对应一个Keyframe集合
Keyframe k1 = Keyframe.ofFloat(0,0);//动画开始,第二个参数不关心是哪个属性
k1.setInterpolator(new LinearInterpolator());
Keyframe k2 = Keyframe.ofFloat(0.5f,360);//动画进行到一半了,第二个参数不关心是哪个属性
k2.setInterpolator(new BounceInterpolator());
Keyframe k3 = Keyframe.ofFloat(1.0f,400);//动画完成,第二个参数不关心是哪个属性
k3.setInterpolator(new BounceInterpolator());
//这里在PropertyValuesHolder里设置需要操作的属性
PropertyValuesHolder pvh = PropertyValuesHolder.ofKeyframe("y",k1,k2,k3);
ObjectAnimator.ofPropertyValuesHolder(imageView,pvh).setDuration(2000).start();

如果我们想操作的对象属性,没有set|get方法,那么我们需要操作时,就可以使用ValueAnimator。下面是抛物线下落的 例子(例子不是很好):

//当对象中某属性没有set/get方法时,就不能使用ObjectAnimator来操作属性动画,这时需要ValueAnimator
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.0f,400f).setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setTarget(imageView);
//每隔10ms就刷新
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
      //ValueAnimator本身不对对象属性进行修改,需要自己来处理。这里实现了抛物线下落
      float value = (float) animation.getAnimatedValue();
      ivPropertyAnim.setX(value);
      ivPropertyAnim.setY(0.08f * value * value);
     }
 });
valueAnimator.start();

Property动画定制

Tween动画中我们可以通过applyTransformation(float interpolatedTime, Transformation t)来自定义动画,也可以通过自定义插值器,覆写getInterpolation方法来定制动画;前面我们通过addUpdateListener来定制ValueAnimator动画,这里我们通过setEvaluator来定制属性动画。

ObjectAnimator.ofFloat(ivPropertyAnim,"x",0f,360f).setDuration(5000).start();
                ObjectAnimator anim1 = ObjectAnimator.ofFloat(ivPropertyAnim,"y",0f,200f).setDuration(5000);
                //定制属性动画
                anim1.setEvaluator(new TypeEvaluator<Float>() {
                    @Override
                    public Float evaluate(float fraction, Float startValue, Float endValue) {
                        System.out.println("fraction=" + fraction +",start="+startValue+",end="+ endValue);
                        return startValue * 0.008f * fraction * (endValue - startValue) * fraction * (endValue - startValue);
                    }
                });
anim1.start();

Property动画扩展

ViewPropertyAnimator

Android API 12时,View中有一个animator()方法,返回ViewPropertyAnimator对象。

myView.animate().xBy(100).yBy(100).alpha(0.5f).rotation(180);

使用比属性动画更加简单。

LayoutAnimator

布局中有View的添加、删除、显示或隐藏时自身动画和View的动画。

  1. LayoutTransition.APPEARING:View添加或出现时显示的动画
  2. LayoutTransition.CHANGE_APPEARING:当添加View导致整个布局改变时布局的动画
  3. LayoutTransition.DISAPPEARING:当View消失或隐藏时View消失的动画
  4. LayoutTransition.CHANGE_DISAPPEARING:删除或隐藏View导致布局改变时布局的动画
  5. LayoutTransition.CHANGING:当不是由于View的原因导致其它View改变时布局的动画。

下面的代码在LinearLayout中动态添加一个按钮时,显示一个动画,从0缩放到正常大小的一个动画。

LayoutTransition layoutTransition = new LayoutTransition();
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("scaleX",0.0f,1.0f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("scaleY",0.0f,1.0f);
                layoutTransition.setAnimator(LayoutTransition.APPEARING,ObjectAnimator.ofPropertyValuesHolder(btn,p1,p2));
linearLayout.setLayoutTransition(layoutTransition);
linearLayout.addView(btn);

Transition动画

Transition动画是个动画框架,主要用于场景的切换动画。从Android4.4引入。Android5.0中,又将Transition动画引入到Activity的切换中实现复杂的动画效果。Material Design中,推荐使用Transition动画实现动画和享元切换。已经内建了一些效果,比如Fade,Explode,Slide。Transition动画封装和抽象了属性动画

  • Scene:保存ViewGroup中所有元素的状态,包括View和属性。
  • Target:Scene里的View对象,可以在Scene中移除和或添加Target对象
  • Transition:Scene切换时所用的动画信息
  • TransitionSet:动画集合
  • TransitionManager:在Scene间施加相应的Transition动画
  • TransitionManager.beginDelayTransiton()
  • TransitionListener:Transition的动画监听。
    Android动画最新最全详解包含Material Design动画_第2张图片

Activity、Fragment切换动画

非享元方式:
Android动画最新最全详解包含Material Design动画_第3张图片

享元方式:
Android动画最新最全详解包含Material Design动画_第4张图片

注意

  • 在SurfaceView上可能表现不正常
  • 在TextureView上施加某些Transition动画,可能达不到预期效果
  • 继承自AdapterView的View,比如ListView可能会出错
  • 对TextView的size施加Transition效果时,文字的位置可能会突变。
  • 不要通过scene的Action在scene间传数据,用callback。

Material Design动画

为了提供更加美观一致的 UI 和更好的交互效果,Android 5.0之后引入了Material Design,其中它对于动画效果有了新的要求,并也提供了6种新的动画类。
Material Design是一种风格、规范、理念和拟物和扁平设计的结合。Material Design要体现物体的三维大小,材质、轻重、弹性。

  • 保留物体的物理特性同时,不失优雅、简约和美丽
  • 动画有利于集中注意力,并保持连续性
  • 反馈要微妙而清晰,过渡动画要高校和连贯。
  • 动画不止增加美丽效果,更加建立空间关系、功能指示、和系统意向功能。

Material Design动画效果

  • 从静止开始要有加速过程,最终静止时要有减速过程
  • 快速进场,则快速退场
  • 弧线转弯,而不是90度转弯
  • 触控反应,涟漪、抬高
  • 从接触点开始动画
  • 视觉连续性,过渡动画引导用户的关注点
  • 层次动画的时间差
  • 移动路径规则有序,随机的移动令用户分心

Touch feedback

触摸反馈。提供了用户与UI交互时可视化的确认接触点。RippleDrawable类做background,涟漪效果在两种不同的状态间过渡。

Reveal effect

物体出现或消失的动画效果。构造方法如下:

ViewAnimationUtils.createCircularReveal(View v, int centerX, int centerY, float startRadius, float endRadius)=>Animator

代码中在点击事件中让一个button显示或消失过程中产生动画:

Animator animator = ViewAnimationUtils.createCircularReveal(
                        btn,
                        btn.getWidth() / 2,
                        btn.getHeight() / 2,
                        0,
                        btn.getWidth());
                animator.setInterpolator(new LinearInterpolator());

                animator.setDuration(6000);
                animator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        super.onAnimationStart(animation);
                        btn.setVisibility(View.VISIBLE);
                    }

                });
animator.start();

Activity transitions

Activity的过渡动画:进入、退出、共享元素下的进、出
进出支持这些transition效果:Explode、Slide和Fade
共享元素transition效果:changeBounds、changeClipBounds、changeTransform、changeImageTransform
Activity.finishAfterTransition()方法,而不是Activity.finish()。

XML方式

在res/transition目录下,可以添加过渡动画的xml文件:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <explode android:duration="2000" />
</transitionSet>
或者
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <fade android:duration="2000" android:fadingMode="fade_in_out"/>
</transitionSet>
或者
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <slide android:duration="2000" android:slideEdge="right" />
</transitionSet>

然后在自定义主题中,设置window的进入退出共享元素下的进出动画:在res/values-v21目录下的style中:

 <style name="myTheme" parent="android:Theme.Material">
        <!-- 允许使用transitions -->
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>

        <!-- 指定进入和退出transitions -->
        <item name="android:windowEnterTransition">@android:transition/explode</item>
        <item name="android:windowExitTransition">@android:transition/explode</item>

        <!-- 指定shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">
            @android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">
            @android:transition/slide_top</item>
    </style>
Java代码方式

在Activity的onCreate中设置过渡动画:

@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        getWindow().setEnterTransition(new Explode().setInterpolator(new BounceInterpolator()).setDuration(2000));
        getWindow().setExitTransition(new Fade().setDuration(2000));
        getWindow().setReturnTransition(new Slide().setDuration(2000));
        getWindow().setReenterTransition(new Slide().setDuration(2000));
        getWindow().setSharedElementReenterTransition(new ChangeTransform().setInterpolator(new BounceInterpolator()).setDuration(2000));

super.onCreate(savedInstanceState);
setContentView(R.layout.first3);
}
在startActivity的地方这样做:
case R.id.transition://过渡动画
                startActivity(new Intent(First3Effect.this, Second3Effect.class), ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
                break;
case R.id.sharetransition://享元模式的过渡动画
View sharedView = findViewById(R.id.p1);
String transitionName = "p1";
ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(First3Effect.this, sharedView, transitionName);

                startActivity(new Intent(First3Effect.this, Second3Effect.class), transitionActivityOptions.toBundle());

如果有多个共享元素
//  ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
//          Pair.create(view1, "agreedName1"),
//          Pair.create(view2, "agreedName2"));

Curved motion

曲线运动。自定义动画时间曲线和曲线运动模式
PathInterpolator类是一个新的基于贝塞尔曲线路径的插值器
系统提供了三种基本的曲线:
1. @interpolator/fast_out_linear_in.xml
2. @interpolator/fast_out_slow_in.xml
3. @interpolator/linear_out_slow_in.xml
ObjectAnimator.ofFloat(view, View.X, View.Y, path);

View state changes

StateListAnimator类定义视图状态变化时的动画效果
layout:android:stateListAnimator
AnimationInflater.loadStateListAnimator()
View.setStateListAnimator()

Animate Vector Drawables

VectorDrawable矢量图片伸缩不失真
AnimatedVectorDrawable矢量图动画
矢量图动画通常包括三类xml文件:
1、<vector>矢量图,在res/drawable/
2、<animated-vector>矢量图,在res/drawable/
3、用<objectAnimator>元素,在res/anim/

本文成自极客学院hexter的学习笔记。

你可能感兴趣的:(android,动画,material)