1、Android中的动画分类

Android中的动画可以分为三类:帧动画,补间动画,和属性动画

动画分类 说明
帧动画 通过不停的播放图片产生的动画效果
补间动画 对View的平移,旋转,缩放,透明产生效果
属性动画 动态的改变属性产生动画效果

2、帧动画及其原理

原理

帧动画是按照一定的顺序播放一系列图片,从而产生动画。和我们看的动漫原理是一样的,本质上是对图片快速的翻页产生动的效果。

帧动画依赖于图片。

示例代码:

<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/rocket_thrust1" android:duration="100" />    <item android:drawable="@drawable/rocket_thrust2" android:duration="100" />    <item android:drawable="@drawable/rocket_thrust3" android:duration="100" />animation-list>

调用

public class MainActivity extends AppCompatActivity {    AnimationDrawable rocketAnimation;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        final ImageView animationImg = (ImageView) findViewById(R.id.imageView);        animationImg.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                animationImg.setImageResource(R.drawable.play);                AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg.getDrawable();                animationDrawable1.setOneShot(true);                animationDrawable1.start();            }        });    }}

3、补间动画及其原理

原理

补间动画的原理是对通过对View的平移,缩放,旋转和透明的操作,从而产生的动画。
注意:补间动画只调整View在Canvas上显示,并没有真实的改变View原来的位置,因此它的点击和触摸事件还保留在没有经过动画前的位置。

动画 说明
平移 移动View的位置 TranslateAnimation
缩放 对View的缩放 ScaleAnimation
旋转 对View的旋转 RotateAnimation
透明 改变View的透明度 AlphaAnimation
<?xml version="1.0" encoding= "utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:fillAfter="true">    <alpha        android:duration="3000"        android:fromAlpha="0.0"        android:toAlpha="1.0" />    <scale        android:duration="3000"        android:fromXScale="0.0"        android:fromYScale="0.0"        android:pivotX="50%"        android:pivotY="50%"        android:toXScale="1.0"        android:toYScale="1.0" />    <rotate        android:duration="3000"        android:fromDegrees="0"        android:pivotX="50%"        android:pivotY="50%"        android:toDegrees="720" />    <translate        android:duration="1000"        android:fromXDelta="0"        android:fromYDelta="0"        android:startOffset="3000"        android:toXDelta="85"        android:toYDelta="0" />set>

补间动画既可以在xml文件中配置,也可以用Java代码实现:

public class MainActivity extends AppCompatActivity {    private ImageView imageView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        imageView = (ImageView) findViewById(R.id.imageView);        TranslateAnimation translateAnim = new TranslateAnimation(0, 200, 0, 200);        translateAnim.setDuration(3000);        translateAnim.setFillAfter(true);        imageView.startAnimation(translateAnim);        imageView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //经过平移后的View不相应点击事件,点击事件仍然在没有移动前。                Toast.makeText(MainActivity.this, "123", Toast.LENGTH_SHORT).show();            }        });    }}

原理

1、调用View的startAnimation()方法出发动画事件。

public void startAnimation(Animation animation) {        animation.setStartTime(Animation.START_ON_FIRST_FRAME);        setAnimation(animation);        invalidateParentCaches();        invalidate(true);    }

在这个方法中,调用invalidate(true),触发调用draw()方法,对view进行重新绘制

2、draw()方法解析
把当前画布中View放置于矩阵中,然后通过矩阵变换对View在画布中影像进行改变。

Transformation 定义的矩阵对象

 boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {        ...        if ((parentFlags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) != 0) {            parent.getChildTransformation().clear();            parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;        }        ...        //矩阵,把当前的View放置到矩阵中        Transformation transformToApply = null;        //对View进行平移,旋转,缩放,透明等事件处理        if (transformToApply != null                || alpha < 1                || !hasIdentityMatrix()                || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {            if (transformToApply != null || !childHasIdentityMatrix) {                int transX = 0;                int transY = 0;                if (offsetForScroll) {                    transX = -sx;                    transY = -sy;                }                if (transformToApply != null) {                    if (concatMatrix) {                        if (drawingWithRenderNode) {                            renderNode.setAnimationMatrix(transformToApply.getMatrix());                        } else {                            // Undo the scroll translation, apply the transformation matrix,                            // then redo the scroll translate to get the correct result.                            canvas.translate(-transX, -transY);                            canvas.concat(transformToApply.getMatrix());                            canvas.translate(transX, transY);                        }                        parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;                    }                    float transformAlpha = transformToApply.getAlpha();                    if (transformAlpha < 1) {                        alpha *= transformAlpha;                        parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;                    }                }                if (!childHasIdentityMatrix && !drawingWithRenderNode) {                    canvas.translate(-transX, -transY);                    canvas.concat(getMatrix());                    canvas.translate(transX, transY);                }            }            // Deal with alpha if it is or used to be <1            if (alpha < 1 || (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) != 0) {                if (alpha < 1) {                    mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;                } else {                    mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;                }                parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;                if (!drawingWithDrawingCache) {                    final int multipliedAlpha = (int) (255 * alpha);                    if (!onSetAlpha(multipliedAlpha)) {                        if (drawingWithRenderNode) {                            renderNode.setAlpha(alpha * getAlpha() * getTransitionAlpha());                        } else if (layerType == LAYER_TYPE_NONE) {                            canvas.saveLayerAlpha(sx, sy, sx + getWidth(), sy + getHeight(),                                    multipliedAlpha);                        }                    } else {                        // Alpha is handled by the child directly, clobber the layer's alpha                        mPrivateFlags |= PFLAG_ALPHA_SET;                    }                }            }        } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {            onSetAlpha(255);            mPrivateFlags &= ~PFLAG_ALPHA_SET;        }        if (!drawingWithRenderNode) {            // apply clips directly, since RenderNode won't do it for this draw            if ((parentFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 && cache == null) {                if (offsetForScroll) {                    canvas.clipRect(sx, sy, sx + getWidth(), sy + getHeight());                } else {                    if (!scalingRequired || cache == null) {                        canvas.clipRect(0, 0, getWidth(), getHeight());                    } else {                        canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());                    }                }            }            if (mClipBounds != null) {                // clip bounds ignore scroll                canvas.clipRect(mClipBounds);            }        }        ...        return more;    }

参考:
https://blog.csdn.net/mr_liabill/article/details/49510485

更多相关文章

  1. android 简单地设置Activity界面的跳转动画
  2. Android平台上大长图(图片很大的那种)的加载原理和方式
  3. Android补间动画详情
  4. 成佩涛编程之路——Android控件动画效果(二)
  5. 问题小结(14)-旋转动画Rotate
  6. Android分包原理
  7. Android(安卓)UI设计之自定义SwitchButton开关,实现类似IOS中UISw
  8. Android实现中轴旋转特效 Android制作别样的图片浏览器
  9. Android内存原理

随机推荐

  1. Android要走路还很长
  2. android eclipse 真机调试
  3. 【摘录】android 屏幕分辨率问题
  4. Android内存管理机制之一:lowmemory kille
  5. 工作日志2015-3-20
  6. Android代码开发性能指引
  7. Android(安卓)activity intent 入门
  8. 什么是Android?
  9. Android(安卓)Framework启动流程浅析
  10. Android中使用Handler机制更新UI的三种解