你必须要知道的动画知识点,Android碎裂的粒子效

作者: 编程应用  发布:2019-09-06

最近看到一段时间都没怎么更新文章了,一直在学习iOS相关内容。偶然间看到一个碎裂的粒子效果,觉得很有意思,就查了查,参考下网上的思路自己撸了个轮子。

Animations

好了,说了这么多,先看看效果吧~

动画系统:Developer-Animation
Android框架提供了两个动画系统:属性动画和视图动画。两个动画系统都是可行的选择,但是总的来说,属性动画系统是首选的方法,因为它更灵活,提供了更多的特性。
android3.0之后 动画分类如图:

image.png

图片 1粒子破碎效果

接下来我们具体讲解这三种动画:


依惯例,先说下行文思路吧,首先我们先简单分析下效果,拆分关注点,粒子效果是怎么产生的?我的解决方案就是先获取当前要碎裂的view的缓存视图,然后根据图片获取各个坐标点的颜色值,在整个DecorView盖上一层视图,这个视图就根据获取的颜色值在要碎裂的view的位置drawCircle,之后变化圆心和半径以及透明度从而产生碎裂效果。那么,我们要解决的问题已经简化为几个点了,看怎么一个一个将其击破。

一、视图动画:【ViewAnimation】

一、获取view的视图二、获取要碎裂的view的位置以及获取各个位置的颜色值三、变化各个属性值产生动画碎裂效果

1. 帧动画(FrameAnimation):它允许您加载可绘制的资源,并将它们显示为一个接一个的帧。一帧一帧的动画,加载一系列Drawable资源来创建动画,这种传统动画某种程度上就是创建不同图片序列,顺序播放,就像电影胶片、幻灯片一样。(这种确实很简单,直接使用UI切好的图就行,但是图片过多,也十分容易内存溢出oom,所以一般不建议使用)

一、获取view的视图

获取view的视图也就是要获取这个视图的截图,有两种方式可以来做:

1、可以用Canvas来获取Bitmap

public Bitmap getBitmapFromView(View view) { Bitmap bmp = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas; view.draw; return bmp;}

2、用getDrawingCache来获取Bitmap

 private static Bitmap getCacheBitmapFromView(View view) { final boolean drawingCacheEnabled = true; view.setDrawingCacheEnabled(drawingCacheEnabled); view.buildDrawingCache(drawingCacheEnabled); final Bitmap drawingCache = view.getDrawingCache(); Bitmap bitmap; if (drawingCache != null) { bitmap = Bitmap.createBitmap(drawingCache); view.setDrawingCacheEnabled; } else { bitmap = null; } return bitmap; }

通过这两种方式都可以获取这个视图的图片,而为什么我们要获取这个视图的图片呢,因为要根据这个图片来获取各个位置的颜色值,为之后绘制粒子效果服务。

2. 补间动画(TweenAnimation) :AlphaAnimation(xml中alpha标签), RotateAnimation(xml中rotate标签), ScaleAnimation(xml中scale标签), TranslateAnimation(xml中translate标签),分别对应透明度、旋转、缩放、位移四种变化。

二、获取要碎裂的view的位置以及获取各个位置的颜色值

获取view的位置,之前使用过getGlobalVisibleRect方法来获取位置,但很多时候并不是很准确,比如有ActionBar的时候。

Rect rect = new Rect();view.getGlobalVisibleRect;

之后测试使用getLocationInWindow这种方式挺不错,这个方法的官方注释为这样写Computes the coordinates of this view in its window.

 int[] location = new int[2]; view.getLocationInWindow; Rect rect = new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight;

在获取视图位置之后,我们要获取各个位置的颜色值来绘制在这片区域内,调用bitmap.getPixel方法获取各个位置的颜色值:

public static Particle[][] generateParticles(Bitmap bitmap, Rect bound) { int w = bound.width(); int h = bound.height(); int partW_Count = w / Particle.PART_WH; int partH_Count = h / Particle.PART_WH; Particle[][] particles = new Particle[partH_Count][partW_Count]; Point point = null; for (int row = 0; row < partH_Count; row ++) { //行 for (int column = 0; column < partW_Count; column ++) { //列 //取得当前粒子所在位置的颜色 int color = bitmap.getPixel(column * Particle.PART_WH, row * Particle.PART_WH); point = new Point(column, row); //x是列,y是行 particles[row][column] = Particle.generateParticle(color, bound, point); } } return particles; }

使用方式一:xml定制动画(文件处于res/anim/地址下)

  • #### alpha xml 淡入效果
<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
<alpha 
    android:fromAlpha="0.0"  
    android:toAlpha="1.0"  
    android:duration="500"  /> 
</set> 
<!--  
    fromAlpha:开始时透明度 
    toAlpha: 结束时透明度 
    duration:动画持续时间 -->
  • #### rotate.xml 旋转效果:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate                                         
      android:interpolator="@android:anim/accelerate_decelerate_interpolator" 
    android:fromDegrees="300" 
    android:toDegrees="-360" 
    android:pivotX="10%" 
    android:pivotY="100%" 
    android:duration="10000" /> 
</set> 
<!--  
  fromDegrees   动画开始时的角度 
  toDegrees     动画结束时物件的旋转角度,正代表顺时针   
  pivotX    属性为动画相对于物件的X坐标的开始位置
----旋转中心的x坐标,浮点数或是百分比。浮点数表示相对于Object的左边缘,如5; 百分比表示相对于Object的左边缘,如5%; 另一种百分比表示相对于父容器的左边缘,如5%p; 一般设置为50%表示在Object中心
  pivotY    属性为动画相对于物件的Y坐标的开始位置 
--- 旋转中心的Y坐标,浮点数或是百分比。浮点数表示相对于Object的上边缘,如5; 百分比表示相对于Object的上边缘,如5%; 另一种百分比表示相对于父容器的上边缘,如5%p; 一般设置为50%表示在Object中心
duration  持续时间,表示从android:fromDegrees转动到android:toDegrees所花费的时间,单位为毫秒。1000ms=1s 可以用来计算速度。
interpolator表示变化率,但不是运行速度。一个插补属性,可以将动画效果设置为加速,减速,匀速,反复,反弹等。默认为开始和结束慢中间快.
其他:
android:repeatCount 重复的次数,默认为0,必须是int,可以为-1表示不停止
android:repeatMode 重复的模式,默认为restart,即重头开始重新运行,可以为reverse即从结束开始向前重新运行。在android:repeatCount大于0或为infinite时生效
android:detachWallpaper 表示是否在壁纸上运行
android:startOffset 在调用start函数之后等待开始运行的时间,单位为毫秒,若为10,表示10ms后开始运行
android:zAdjustment 表示被animated的内容在运行时在z轴上的位置,默认为normal。
normal保持内容当前的z轴顺序
top运行时在最顶层显示
bottom运行时在最底层显示
   -->
  • #### scale.xml 缩放效果:
<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
<scale   
    android:interpolator= "@android:anim/decelerate_interpolator"       
    android:fromXScale="0.0"   
    android:toXScale="1.5"   
    android:fromYScale="0.0"   
    android:toYScale="1.5"   
    android:pivotX="50%"   
    android:pivotY="50%"   
    android:startOffset="0"   
    android:duration="10000"  
    android:repeatCount="1"   
    android:repeatMode="reverse"  /> 
</set> 

<!--  
fromXDelta,fromYDelta       起始时X,Y座标,屏幕右下角的座标是X:320,Y:480 
toXDelta, toYDelta      动画结束时X,Y的座标 --> <!--  
interpolator                    指定动画插入器
常见的有加速减速插入器         accelerate_decelerate_interpolator
加速插入器               accelerate_interpolator,
减速插入器               decelerate_interpolator。 
fromXScale,fromYScale,         动画开始前X,Y的缩放,0.0为不显示,  1.0为正常大小
toXScale,toYScale,          动画最终缩放的倍数, 1.0为正常大小,大于1.0放大
pivotX,  pivotY         动画起始位置,相对于屏幕的百分比,两个都为50%表示动画从屏幕中间开始 
startOffset,                动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间,
                    单位毫秒 duration,一次动画效果消耗的时间,单位毫秒,
                    值越小动画速度越快 repeatCount,动画重复的计数,动画将会执行该值+1次 
                    repeatMode,动画重复的模式,reverse为反向,当第偶次执行时,动画方向会相反。
                    restart为重新执行,方向不变 -->
  • #### translate.xml 移动效果:
<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate 
    android:fromXDelta="320" 
    android:toXDelta="0" 
    android:fromYDelta="480" 
    android:toYDelta="0" 
    android:duration="10000" /> 
</set> 
<!--  
fromXDelta,fromYDelta   起始时X,Y座标,屏幕右下角的座标是X:320,Y:480 
toXDelta, toYDelta     动画结束时X,Y的座标 -->

三、变化各个属性值产生动画碎裂效果

首先我们要在当前视图上覆盖一层产生碎裂效果的视图:

 private void attachToActivity(Activity activity) { ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView(); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); rootView.addView; }

将我们要绘制粒子动画效果的添加进布局视图中,然后我们就可以开始绘制了。开启属性动画,根据动画流程变化Particle的相关属性:

 //x值 public float cx; //y值 public float cy; //绘制圆的半径 public float radius; //颜色 public int color; //透明度 public float alpha;

在自定义视图的onDraw方法,遍历所有我们保存的粒子Particle,改变相关属性值:

@Override protected void onDraw(Canvas canvas) { if (mParticleAnimator !=null) drawParticle; } public void drawParticle(Canvas canvas) { //动画结束停止 if(!mParticleAnimator.isRunning { return; } for (Particle[] particle : mParticleAnimator.getParticles { for (Particle p : particle) { p.update mParticleAnimator.getAnimatedValue; mPaint.setColor; mPaint.setAlpha (Color.alpha * p.alpha)); canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);// } } invalidate(); } //更新相关属性值 主要是随机生成x y值以及碎裂大小 public void update(float factor) { cx = cx + factor * random.nextInt(mBound.width * (random.nextFloat; cy = cy + factor * (mBound.height()/(random.nextInt ; radius = radius - factor * random.nextInt;; if (radius<=0) radius = 0; alpha = 1f - factor; }

OK,到这里我们就基本实现了这个碎裂效果,整体注意点基本就这么多,我把它简单封装了下,使用方式也很简单:

 final ParticleView particleAnimator = new ParticleView(MainActivity.this,3000);//3000为动画持续时间 particleAnimator.setOnAnimationListener(new ParticleView.OnAnimationListener() { @Override public void onAnimationStart(View view,Animator animation) { //动画开始 view.setVisibility(View.INVISIBLE); } @Override public void onAnimationEnd(View view,Animator animation) { //动画结束 } }); findViewById.setOnClickListener(new View.OnClickListener() { @Override public void onClick { particleAnimator.boom;//开始动画 } });

github地址:ParticleDismissLayout

加载xml动画:

//xml动画文件
ImageView imageBg = (ImageView) content.findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(context, R.anim.splash_scale);
animation.setInterpolator(new LinearInterpolator());
imageBg.startAnimation(animation);

使用方式二、java代码方式实现定制并加载动画

xml里有的动画属性都可以通过java代码创建。根据需要定制自己的动画

//平移动画 四个参数fromX,toX,fromY,toY。而这个X,Y都是相对于当前这个控件的位置来说的。
//就是从当前控件的(X+fromX,Y+fromY)移动到(X+toX,Y+toY),
//(其中这个X和Y是最刚开始这个控件的X和Y坐标。就是动画都还没开始的时候的坐标。)
ImageView imageBg = (ImageView) content.findViewById(R.id.imageView);
TranslateAnimation anim = new TranslateAnimation(0,100,0,100);
anim.setDuration(5000);
anim.setInterpolator(new LinearInterpolator());
anim.setFillAfter(true);
imageBg .startAnimation(anim);

AnimationListener和AnimationSet

通过AnimationListener可以监听Animation的运行过程,有三个方法分别是Animation开始的时候调用,完成的时候调用,重复的时候调用。
AnimationSet,动画集合。 我们最常用的是调用其 addAnimation 将一个个不一样的动画组织到一起来,然后调用view 的 startAnimation 方法触发这些动画执行。

            AnimationSet as=new AnimationSet(true);  
            RotateAnimation al=new RotateAnimation(0,-720,Animation.RELATIVE_TO_PARENT,0.5f,Animation.RELATIVE_TO_PARENT,0.5f);  
            al.setDuration(3000);  
            al.setAnimationListener(new AnimationListener(){  

                public void onAnimationStart(Animation animation) {  
                    // TODO Auto-generated method stub  

                }  

                public void onAnimationEnd(Animation animation) {  
                    // TODO Auto-generated method stub  

                }  

                public void onAnimationRepeat(Animation animation) {  
                    // TODO Auto-generated method stub  

                }  

            });  
            as.addAnimation(al);  
            iv.startAnimation(as);  

setAnimation和startAnimation区别

setAnimation是告诉该控件我待会要执行什么动画,而要执行的的动画,是需要手动添加的。并且需要父view在动画快要开启的时候,调用invalidate。需要一定的条件限制。
而startAnimation告诉该控件,我要立马执行该动画,该动画就是已经设置好的动画。调用它时就会立即开始动画。


属性动画 【PropertyAnimation】

对比

ViewAnimation本身是通过改变View的绘制方式来实现动画的,View对象本身的属性值并没有改变,对象仍然停留在原始位置.
Property Animation系统可以通过修改 View 对象实际的属性值(属性会有相应的 getter、setter )来实现屏幕上的动画效果。此外,当属性值发生变化时,Views 也会自动调用 invalidate() 方法来刷新屏幕。

View Animation相当简单,不过只能支持简单的缩放、平移、旋转、透明度基本的动画和帧动画,且有一定的局限性。比如:

  • 你希望View有一个颜色的切换动画;
  • 你希望可以使用3D旋转动画;
  • 你希望当动画停止时,View的位置就是当前的位置;
  • 修改组件的背景颜色
    这些View Animation都无法做到。
    这也就是Property Animation产生的原因。
    PropertyAnimation就是通过动画的方式改变对象的属性。
    接下来我们详细讲解PropertyAnimation。
1.PropertyAnimation-沿一定时间顺序,通过改变View的属性,从而得到动画效果。使得“眼见为实”,动画之后,Object对象的属性值被实实在在的改变了。Property animation能够通过改变View对象的实际属性来实现View动画,任何时候View属性的改变,View能自动调用invalidate()来实时刷新。
2.总的来说,属性动画就是,动画的执行类来设置动画操作的对象的属性(持续时间,开始和结束的属性值,时间差值等),然后系统会根据设置的参数动态的变化对象的属性。
  • 动画的执行类:
    • ObjectAnimator
    • ValueAnimator
  • 对象的属性:
    • Duration:动画的持续时间,默认300ms
    • Time Interpolation : 时间插值【LinearInterpolator、AccelerateInterpolator、DecelerateInterpolator等】
    • Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。
    • Animator sets : 动画集合,你可以定义一组动画,一起执行或者顺序执行。
  • 其他重要的类:
    • AnimatorInflater 用户加载属性动画的xml文件
    • TypeEvaluator 类型估值,主要用于设置动画操作属性的值。
    • TimeInterpolator 时间插值
    • AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等。
    • PropertyValuesHolder 针对同一个对象多个属性,同时作用多种动画

接下来讲解属性动画在实践中的使用:

【关于Interpolator、TypeEvaluator】

参看这篇文章:Android动画之Interpolator插补器和TypeEvaluator估值器

【关于Animator监听器 】

Property Animation提供了Animator.AnimatorListener和Animator.AnimatorUpdateListener两个监听器用于动画在播放过程中的重要动画事件。下面是两个监听器接口和方法的一些介绍和说明:

  • Animator.AnimatorListener:
    onAnimationStart() —— 动画开始时调用;
    onAnimationEnd() —— 动画结束时调用;
    onAnimationRepeat() —— 动画循环播放时调用;
    onAnimationCancel() —— 动画被取消时调用。不管终止的方式如何,被取消的动画仍然会调onAnimationEnd();
    • 此监听器还有一个子类AnimatorListenerAdapter,两者的区别是AnimatorListener的方法需要全部实现,而AnimatorListenerAdapter可以选择我们所需要的方法实现,比如通常情况我们只关心onAnimationEnd。
       animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {

            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
  • Animator.AnimatorUpdateListener(通常和ValueAnimator搭配使用):
    onAnimationUpdate() —— 动画每播放一帧时调用。
    在动画过程中,可侦听此事件来获取并使用 ValueAnimator 计算出来的属性值;
    利用传入事件的 ValueAnimator 对象,调用其 getAnimatedValue() 方法即可获取当前的属性值。如果使用ValueAnimator来实现动画的话 ,则必需实现此侦听器。

【关于AnimatorInflater】

上面讲到ViewAnimation有许多xml加载,当然PropertyAnimation也可以对应xml加载,位置为res/animator/
animator.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:propertyName="alpha"
android:valueFrom="0.1"
android:valueTo="1.0"
android:valueType="floatType" />

调用就用到了AnimatorInflater类了

 Animator animator = AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.animator);
animator.setTarget(imageView);
animator.start();

组合动画也可以xml加载

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
orderring属性设置为together,还有另一个值:sequentially(表示一个接一个执行)。
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" />
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" />
</set>

【关于动画属性值】

在 Android 3.0 中给 View 增加了一些新的属性以及相应的 getter、setter 方法。Property Animation系统可以通过修改 View 对象实际的属性值来实现屏幕上的动画效果。此外,当属性值发生变化时,Views 也会自动调用 invalidate() 方法来刷新屏幕。 View 类中新增的便于实现 property 动画的属性包括:

  • translationX和translationY:增量控制view的坐标偏移
  • rotation、rotationX 和 rotationY:这三个属性控制着 2D 旋转角度(rotation属性)和围绕某枢轴点的 3D 旋转角度;
  • scaleX、scaleY:控制view绕支点进行2D缩放
  • x 和 y:这是指 View 在容器内的最终位置,等于 View 左上角相对于容器的坐标加上 translationX 和 translationY 后的值;
  • alpha:表示 View 的 alpha 透明度。缺省值为 1 (不透明),为 0 则表示完全透明(看不见);

上述我们提到的属性也就是接下来ObjectAnimator使用中的第二个参数,操作对象的属性值。

当然我们也可以自定义view的动画属性,但必须带有一个 setter 方法(以骆驼拼写法命名),格式类似 set<propertyName>()。 因为 ObjectAnimator 会在动画期间自动更新属性值,它必须能够用此 setter 方法访问到该属性。getter不是必须,而什么时候必须需要getter方法呢?如果在调用 ObjectAnimator 的某个工厂方法时,我们只为 values... 参数指定了一个值,那此值将被认定为动画属性的结束值。 这样的话,动画显示的属性必须带有一个 getter 方法,用于获取动画的起始值。 此 getter 方法必须以get<propertyName>()的格式命名。

【使用ObjectAnimator实现动画】

  • #### 关于使用ObjectAnimator实现动画的步骤和实践

1.通过调用ofFloat()、ofInt()等方法创建ObjectAnimator对象,并设置目标对象、需要改变的目标属性名、初始值和结束值;
2.设置动画的持续时间、是否重复及重复次数等属性;
3.启动动画。

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "translationX", 300);
objectAnimator1.setInterpolator(new AccelerateInterpolator());
objectAnimator1.setDuration(2000);
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);//Animation.INFINITE 表示重复多次
objectAnimator.setRepeatMode(ValueAnimator.RESTART);//RESTART表示从头开始,REVERSE表示从末尾倒播
objectAnimator1.start();

1 . 第一个参数:设置目标对象,即操纵的view
2 . 第二个参数:设置操作的动画的属性值(见上面讲解的动画属性值)
3 . 第三个参数:可变数组参数 (初始值,中间值,结束值)。可以有一个到N个,如果是一个值的话默认这个值是动画过渡值的结束值。如果有N个值,动画就在这N个值之间过渡。

【使用ValueAnimator实现动画】

  • #### 关于使用ValueAnimator实现动画的步骤及实践

**那一般使用ValueAnimator实现动画分为以下七个步骤:

  1. 调用ValueAnimation类中的ofInt(int...values)、ofFloat(String propertyName,float...values)等静态方法实例化ValueAnimator对象,并设置目标属性的属性名、初始值或结束值等值;
    2.调用addUpdateListener(AnimatorUpdateListener mListener)方法为ValueAnimator对象设置属性变化的监听器;
    3.创建自定义的Interpolator,调用setInterpolator(TimeInterpolator value)为ValueAniamtor设置自定义的Interpolator;(可选,不设置默认为缺省值)
    4.创建自定义的TypeEvaluator,调用setEvaluator(TypeEvaluator value)为ValueAnimator设置自定义的TypeEvaluator;(可选,不设置默认为缺省值)
    5.在AnimatorUpdateListener 中的实现方法为目标对象的属性设置计算好的属性值。
    6.设置动画的持续时间、是否重复及重复次数等属性;
    7.为ValueAnimator设置目标对象并开始执行动画。**

【ObjectAnimator和ValueAnimator的对比】

  • ObjectAnimator类作为ValueAnimator的子类不仅继承了ValueAnimator的所有方法和特性,并且还封装很多实用的方法,方便开发人员快速实现动画。
  • ObjectAnimator属性值会自动更新,使用ObjectAnimator实现动画不需要像ValueAnimator那样必须实现 ValueAnimator.AnimatorUpdateListener ,因此实现任意对象的动画显示就更加容易了。
  • ValueAnimator并没有在属性上做操作,不需要操作的对象的属性一定要有getter和setter方法,你可以自己根据当前动画的计算值,来操作任何属性。

【PropertyValuesHolder】

针对同一个对象多个属性,同时作用多种动画

PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f);
PropertyValuesHolder propertyValuesHolder3 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder propertyValuesHolder4 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder1, propertyValuesHolder2, propertyValuesHolder3, propertyValuesHolder4)
        .setDuration(5000).start();

【关于AnimatorSet动画集合】

可以调用其playTogether(同时执行)、playSequentially(顺序执行)、play、before、with、after 等方法设置动画的执行顺序,然后调用其start 触发动画执行。

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0.5f);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView, "translationY", 300);
ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(5000);
animatorSet.playTogether(objectAnimator1, objectAnimator2,objectAnimator3);
animatorSet.start();
AnimatorSet 和 AnimationSet 区别

AnimationSet 与 AnimatorSet 最大的不同在于:
AnimationSet 使用的是 Animation 子类、AnimatorSet 使用的是 Animator 的子类。
-----Animation 是针对视图外观的动画实现,动画被应用时外观改变但视图的触发点不会发生变化,还是在原来定义的位置。 (也就是作用于视图动画)
-----Animator 是针对视图属性的动画实现,动画被应用时对象属性产生变化,最终导致视图外观变化。(也就是作用于属性动画)

AnimatorSet 和 PropertyValuesHolder 区别

AnimatorSet可以将作用于多个view多个属性的动画集合起来,而PropertyValuesHolder针对同一个对象多个属性。

AnimatorSet多了playTogether(同时执行)、playSequentially(顺序执行)、play(objectAnimator1).with(objectAnimator2)、before、after这些方法协同工作。

【关于View的animate方法】

Android 3.0后,谷歌给View增加animate方法直接驱动属性动画。

可以直接这样写就完成了imageview 的透明度有1-0.5以及位置移动到300动画:
imageView.animate()
.alpha(0.5f)
.y(300)
.setDuration(2000);

此后在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前,和动画后执行一些操作。
当然也可以.setListener(listener)等操作
                imageView.animate()//
                .alpha(0)//  由1到0
                .y(mScreenHeight / 2)
                .setDuration(1000)  
                // need API 12  
                .withStartAction(new Runnable()  
                {  
                    @Override  
                    public void run()  
                    {  
                    }  
                    // need API 16  
                }).withEndAction(new Runnable()  
                {  

                    @Override  
                    public void run()  
                    {  

                        runOnUiThread(new Runnable()  
                        {  
                            @Override  
                            public void run()  
                            {  
                                imageView.setY(0);  
                                imageView.setAlpha(1.0f);  
                            }  
                        });  
                    }  
                }).start();  
其实上面的这段操作通过PropertyValuesHolder也可以实现:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,  
            0f, 1f);  
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0,  
            mScreenHeight / 2, 0);  
ObjectAnimator.ofPropertyValuesHolder(imageView, pvhX, pvhY).setDuration(1000).start();  

【布局动画】

Android动画学习之为ViewGroup中的Layout设置动画实例

之后会总结出一篇动画实践的文章,汇总一些好看的常用的动画。

最后的最后不要吝啬你的小心心❤️ 你们的鼓励是我最大的动力~

本文由今晚开什么码发布于编程应用,转载请注明出处:你必须要知道的动画知识点,Android碎裂的粒子效

关键词: