Android动画的学习

常见的动画分为:

-补间动画
-帧动画
- 属性动画


学完这个分享自己项目一个简单的动画:

转场动画:这个是谷歌提供的样式!下面自己模仿了一下。

模仿谷歌设计来自己做了一个。

一补间动画:

对于学过flash动画的人来说补间动画很好理解的,因为动画开始和结尾的中间过程都是假象,是渲染出来的表象,只是显示的位置变动,View的实际位置未改变,表现为View移动到其他地方,点击事件仍在原处才能响应。

补间动画由Animation类来实现具体效果,包括平移(TranslateAnimation)、缩放(ScaleAnimation)、旋转(RotateAnimation)、透明度(AlphaAnimation)四个子类。

实现:

补间动画在android里面支持xml来设置或者java代码设置。
常见的布局动画类如下:

TranslateAnimation

translate属性 TranslateAnimation 含义
android:fromXDelta TranslateAnimation translateAnimation=TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta); 平移起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点50%表示以当前View的左上角加上当前View宽高的50%做为初始点50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:fromYDelta 同上 同理fromXDelta
android:toXDelta 同上 平移终点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点50%表示以当前View的左上角加上当前View宽高的50%做为初始点50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
android:toYDelta 同上 同上
android:fillAfter translateAnimation.setFillAfter(true); 动画显示结束保持最后一帧
android:duration translateAnimation.setDuration(3000); 动画执行的时间
android:repeatCount translateAnimation.setRepeatCount(TranslateAnimation.INFINITE); 动画执行的次数可以是整数或者infinite为无限循环执行动画

使用如下:

translate.xml
<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXDelta="0"    android:fromYDelta="0"    android:toXDelta="100%"    android:toYDelta="-100%"    android:fillAfter="true"    android:duration="1000"    >translate>

AlphaAnimation

Alpha属性 AlphaAnimation 含义
android:fromAlpha AlphaAnimation alphaAnimation=new AlphaAnimation(float fromAlpha, float toAlpha); 是View视图起始透明度,透明度是0-1
android:toAlpha 同上 结束时的透明度
android:fillAfter alphaAnimation.setFillAfter(true); 动画显示结束保持最后一帧
android:duration alphaAnimation.setDuration(3000); 动画执行的时间
android:repeatCount alphaAnimation.setRepeatCount(TranslateAnimation.INFINITE); 动画执行的次数可以是整数或者infinite为无限循环执行动画

使用如下:

alpha.xml
<?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:fromAlpha="1"    android:toAlpha="0.5"    android:fillAfter="true"    android:duration="3000"    >alpha>

RotateAnimation

RotateAnimation 属性 RotateAnimation 含义
android:fromDegrees RotateAnimation rotateAnimation=RotateAnimation(float fromDegrees, float toDegrees); 是View视图起始角度
android:toDegrees 同上 结束时的角度
android:fillAfter rotateAnimation.setFillAfter(true); 动画显示结束保持最后一帧
android:duration rotateAnimation.setDuration(3000); 动画执行的时间
android:repeatCount rotateAnimation.setRepeatCount(TranslateAnimation.INFINITE); 动画执行的次数可以是整数或者infinite为无限循环执行动画

使用如下:

rotate.xml
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android"    android:fromDegrees="0"    android:toDegrees="90"    android:fillAfter="true"    android:duration="3000"    >rotate>

ScaleAnimation

ScaleAnimation属性 ScaleAnimation 含义
android:fromXScale ScaleAnimation scaleAnimation=ScaleAnimation(float fromX, float toX, float fromY, float toY) 这个相信能看懂。
android:toXScale 同上 结束时的位置
android:fillAfter scaleAnimation.setFillAfter(true); 动画显示结束保持最后一帧
android:duration scaleAnimation.setDuration(3000); 动画执行的时间
android:repeatCount scaleAnimation.setRepeatCount(TranslateAnimation.INFINITE); 动画执行的次数可以是整数或者infinite为无限循环执行动画

使用如下:

scale .xml
<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"    android:fromXScale="0.5"    android:toXScale="1"    android:fromYScale="0.5"    android:toYScale="1"    android:fillAfter="true"    android:duration="3000"    >scale>

AnimationSet

当然了有动画集合这个类了。使用也是很简单的:

set.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:fillAfter="true"    android:shareInterpolator="true"    android:repeatMode="reverse"    >    <scale        android:duration="1000"        android:fillAfter="true"        android:fromXScale="0.5"        android:fromYScale="0.5"        android:toXScale="1"        android:toYScale="1"        android:repeatCount="infinite"/>    <alpha        android:duration="2000"        android:fillAfter="true"        android:fromAlpha="0.7"        android:toAlpha="1"/>    <rotate        android:fromDegrees="0"        android:toDegrees="90"        android:fillAfter="true"        android:duration="1000"        />    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="100%"        android:toYDelta="-100%"        android:fillAfter="true"        android:duration="2000"        />set>
button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                /*                //位移动画                Animation animation= AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate);                button.setAnimation(animation);                TranslateAnimation translateAnimation=new TranslateAnimation(0,200,0,200);                AlphaAnimation translateAnimation=new AlphaAnimation(0.5f,1f);                translateAnimation.setDuration(3000);                translateAnimation.setRepeatMode(TranslateAnimation.INFINITE);                translateAnimation.setRepeatCount(TranslateAnimation.INFINITE);                translateAnimation.setFillAfter(true);                */               /*                //渐变动画                AlphaAnimation alphaAnimation=new AlphaAnimation(0.5f,1f);                alphaAnimation.setDuration(3000);                alphaAnimation.setRepeatMode(TranslateAnimation.INFINITE);                alphaAnimation.setRepeatCount(TranslateAnimation.INFINITE);                alphaAnimation.setFillAfter(true);                button.startAnimation(alphaAnimation);*/               /*               * //旋转动画               * public RotateAnimation(float fromDegrees, float toDegrees) {               *                RotateAnimation rotateAnimation=new RotateAnimation(0,90);                rotateAnimation.setDuration(3000);                rotateAnimation.setRepeatMode(TranslateAnimation.INFINITE);                rotateAnimation.setRepeatCount(TranslateAnimation.INFINITE);                rotateAnimation.setFillAfter(true);                button.startAnimation(rotateAnimation);*/               /*               * 缩放动画               *               *                ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 0.7f, 0.5f, 0.7f);                scaleAnimation.setDuration(3000);                scaleAnimation.setRepeatMode(TranslateAnimation.INFINITE);                scaleAnimation.setRepeatCount(TranslateAnimation.INFINITE);                scaleAnimation.setFillAfter(true);                button.startAnimation(scaleAnimation); */                AlphaAnimation alphaAnimation=new AlphaAnimation(0.5f,1f);                alphaAnimation.setDuration(3000);                alphaAnimation.setRepeatMode(TranslateAnimation.INFINITE);                alphaAnimation.setRepeatCount(TranslateAnimation.INFINITE);                alphaAnimation.setFillAfter(true);                button.startAnimation(alphaAnimation);                RotateAnimation rotateAnimation=new RotateAnimation(0,90);                rotateAnimation.setDuration(3000);                rotateAnimation.setRepeatMode(TranslateAnimation.INFINITE);                rotateAnimation.setRepeatCount(TranslateAnimation.INFINITE);                rotateAnimation.setFillAfter(true);                button.startAnimation(rotateAnimation);                ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 0.7f, 0.5f, 0.7f);                scaleAnimation.setDuration(3000);                scaleAnimation.setRepeatMode(TranslateAnimation.INFINITE);                scaleAnimation.setRepeatCount(TranslateAnimation.INFINITE);                scaleAnimation.setFillAfter(true);                button.startAnimation(scaleAnimation);                //动画集合                AnimationSet animationSet=new AnimationSet(true);                animationSet.addAnimation(alphaAnimation);                animationSet.addAnimation(rotateAnimation);                animationSet.addAnimation(scaleAnimation);                animationSet.setDuration(2000);                animationSet.setRepeatMode(AnimationSet.INFINITE);                animationSet.setRepeatCount(AnimationSet.INFINITE);                button.setAnimation(animationSet);            }        });

效果图如下:

1.给简单的view控件设置动画:

2.给Activity设置转场动画:

缩放,淡入淡出,滑进滑出….很多由你来设置:这里为了演示效果设置时间很长。用时候可以设置短。
如下图:第一个页面跳转第二个Activity页面动画效果:

淡入淡出的:

这里在demon里面activity跳转动画都写了好多开参考。

可能很多人不明白100%p和100%这样的问题。明确知道左下角为坐标原点。看看别人的博客就懂了

如上图:Activity A从-100%p滑到0即从位置一滑到位置二。很简单的理解。看图就知道了。

二,属性动画:

由于3.0之前的View动画太过单一,不能够满足开发和用户,所以谷歌在3.0之后提出了属性动画
,属性动画是从3.0及以后出现的(如果要兼容低版本,可以使用一个民间版第三方的一个jar NineOldAndroid.jar,用法跟系统的用法差不多)。不断地控制控件的属性变化达到动画的效果,一般我们是一些组合的属性动画达到复杂的效果。

使用:

使用1:

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f);        objectAnimator.setDuration(4000);        objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);        objectAnimator.start();        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, "translationY", 0f, 300f);        objectAnimator1.setDuration(7000);        objectAnimator1.setRepeatCount(ObjectAnimator.INFINITE);        objectAnimator1.start();        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, "scaleX", 0.2f, 1f);        objectAnimator2.setDuration(6000);        objectAnimator2.setRepeatCount(ObjectAnimator.INFINITE);        objectAnimator2.start();        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(view, "scaleY", 0.2f, 1f);        objectAnimator3.setDuration(6000);        objectAnimator3.setRepeatCount(ObjectAnimator.INFINITE);        objectAnimator3.start();        ObjectAnimator objectAnimator4=ObjectAnimator.ofFloat(view,"alpha",0.5f,1f);        objectAnimator4.setDuration(6000);        objectAnimator4.setRepeatCount(ObjectAnimator.INFINITE);        objectAnimator4.start();

使用2:

ObjectAnimator animator = ObjectAnimator.ofFloat(button, "haha", 0f, 100f);//没有这个属性的时候,就是valueanimator        animator.setDuration(300);        //设置动画监听        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //动画在执行的过程当中,不断地调用此方法//              animation.getAnimatedFraction()//百分比                //得到duration时间内 values当中的某一个中间值。0f~100f                float value = (float) animation.getAnimatedValue();//                button.setScaleX(0.5f+value/200);//0.5~1                button.setScaleY(0.5f+value/200);//0.5~1            }        });        animator.start();

使用3:

  ValueAnimator valueAnimator=ValueAnimator.ofFloat(0f,200f);        valueAnimator.setDuration(200);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //              //动画在执行的过程当中,不断地调用此方法////            animation.getAnimatedFraction()//百分比//          //得到duration时间内 values当中的某一个中间值。0f~100f                float value = (float) animation.getAnimatedValue();//                button.setScaleX(0.5f + value / 200);//0.5~1                button.setScaleY(0.5f + value / 200);//0.5~1            }        });        valueAnimator.start();

使用4:

//3)方法3        //float... values:代表关键帧的值        PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1f,0.7f,1f);        PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f,0.7f,1f);        PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f,0.7f,1f);//      PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("translationX", 0f,300f);        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(button, holder1,holder2,holder3);        animator.setDuration(1000);        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                // TODO Auto-generated method stub                float animatedValue = (float) animation.getAnimatedValue();                float animatedFraction = animation.getAnimatedFraction();                long playTime = animation.getCurrentPlayTime();                System.out.println("animatedValue:"+animatedValue+",  playTime:"+playTime);            }        });        animator.start();

动画集合:

    //4)方法4:-----------------动画集合--------------------        ObjectAnimator animator1 = ObjectAnimator.ofFloat(button,"alpha", 1f,0.7f,1f);        ObjectAnimator animator2 = ObjectAnimator.ofFloat(button,"scaleX", 1f,0.7f,1f);        ObjectAnimator animator3 = ObjectAnimator.ofFloat(button,"scaleY", 1f,0.7f,1f);        AnimatorSet animatorSet = new AnimatorSet();        animatorSet.setDuration(500);//      animatorSet.play(anim);//执行当个动画//      animatorSet.playTogether(animator1,animator2,animator3);//同时执行        animatorSet.playSequentially(animator1,animator2,animator3);//依次执行动画        animatorSet.start();

实现一个抛物线:

首先抛物线方程:水平方向:x:匀速运动:
竖着方向:y=1/2*g*t*t

        ValueAnimator valueAnimator=new ValueAnimator();        valueAnimator.setDuration(4000);        valueAnimator.setObjectValues(new PointF(0,0));//起点坐标        //估值器:====定义计算规则        valueAnimator.setEvaluator(new TypeEvaluator() {            @Override            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {                //拿到每一个时间点的坐标:                //x                PointF pointF=new PointF();                //x=vt                pointF.x=100f*fraction*4;//初始速度*执行的百分比                pointF.y=0.5f*100f*(fraction*4)*(fraction*4);//为了30明显我把g设置成                return pointF;            }        });        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //得到此事件点的坐标                PointF pointF= (PointF) animation.getAnimatedValue();                button.setX(pointF.x);                button.setY(pointF.y);            }        });        valueAnimator.start();

案例代码:

 //2017年11月10日:实现点击旋转动画这个有点小复杂        ibTop.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (isWmflag) {//如果是女生                    if (count % 2 == 0 && endOther) {//如果在人体前面进行点击旋转进行旋转动画且切换图片哦                        endOther = false;                        ObjectAnimator oa = ObjectAnimator.ofFloat(home_man_iv, "rotationY",                                new float[]{0f, 60f, 120f, 180f});                        oa.setDuration(1000);                        oa.setRepeatCount(0);                        oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                            @Override                            public void onAnimationUpdate(ValueAnimator animation) {                                //这个值是获取对应的什么时间进行切换图片。首先设置了0f,60f,120f,180f这四个插入值作为旋转角度,当90度时候我们来切换背景图片达到旋转切换。                                float playTime = (float) animation.getAnimatedValue();                                if (playTime >= 90) {                                    home_man_iv.setBackgroundResource(R.drawable.female_b);                                }                                //当180度时候我们进行标记。这个旋转结束了。可以点击进行下一个动画了。endOther作为标记。                                if (playTime == 180f) {                                    count++;                                    endOther = true;                                }                            }                        });                        oa.start();                    } else if (endOther) {//如果是女生                        endOther = false;                        ObjectAnimator oa = ObjectAnimator.ofFloat(home_man_iv, "rotationY",                                new float[]{0f, 60f, 120f, 180f});                        oa.setDuration(1000);                        oa.setRepeatCount(0);                        oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                            @Override                            public void onAnimationUpdate(ValueAnimator animation) {                                float playTime = (float) animation.getAnimatedValue();                                if (playTime >= 90) {                                    home_man_iv.setBackgroundResource(R.drawable.female_f);                                }                                if (playTime == 180f) {                                    count++;                                    endOther = true;                                }                            }                        });                        oa.start();                    }                } else {                    if (count % 2 == 0 && endOther) {                        endOther = false;                        ObjectAnimator oa = ObjectAnimator.ofFloat(home_man_iv, "rotationY",                                new float[]{0f, 60f, 120f, 180f});                        oa.setDuration(1000);                        oa.setRepeatCount(0);                        oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                            @Override                            public void onAnimationUpdate(ValueAnimator animation) {                                float playTime = (float) animation.getAnimatedValue();                                if (playTime >= 90) {                                    home_man_iv.setBackgroundResource(R.drawable.male_b);                                }                                if (playTime == 180f) {                                    count++;                                    endOther = true;                                }                            }                        });                        oa.start();                    } else if (endOther) {                        endOther = false;                        ObjectAnimator oa = ObjectAnimator.ofFloat(home_man_iv, "rotationY",                                new float[]{0f, 60f, 120f, 180f});                        oa.setDuration(1000);                        oa.setRepeatCount(0);                        oa.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {                            @Override                            public void onAnimationUpdate(ValueAnimator animation) {                                float playTime = (float) animation.getAnimatedValue();                                if (playTime >= 90) {                                    home_man_iv.setBackgroundResource(R.drawable.male_f);                                }                                if (playTime == 180f) {                                    count++;                                    endOther = true;                                }                            }                        });                        oa.start();                    }                }            }        });

转场动画:
ActivityOptions类作为谷歌提供的转场效果类如果用过的很简单哦。
首先xml里面用android:transitionName作为标记给共享的view。
下面recylerView里面item中item

 <ImageView     android:transitionName="ivtraname"     android:id="@+id/item_iv"     android:layout_width="match_parent"     android:layout_height="180dp"/>

这个是跳转后的布局里面:

 <ImageView        android:background="@mipmap/rv0"        android:transitionName="ivtraname"        android:scaleType="fitXY"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_weight="1" />

sharedElement是ImageView共享View
sharedElementName=tansitionName的名称=ivtraname

public static ActivityOptions makeSceneTransitionAnimation(Activity activity,            View sharedElement, String sharedElementName) {        return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));    }@SafeVarargs    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,            Pair... sharedElements) {

使用也是很简单的:这里我使用的是兼容包类

 ActivityOptionsCompat optionsCompat1 = ActivityOptionsCompat.makeSceneTransitionAnimation((Activity) context,(View)holder.miv,"ivtraname");                Intent intent = new Intent(context, Main3Activity.class);                context.startActivity(intent, optionsCompat1.toBundle());//最低兼容16

效果如下:

demon地址如下:
https://github.com/luhenchang/Lsn22_SceneTransitionAnimation.git
如果有所不对地方请多多指教,相互学习!!!!
https://github.com/luhenchang/Lsn20_PropertyAnimation.git

更多相关文章

  1. Android图形---OpenGL(三)
  2. [置顶] 关于代码家(干货集中营)共享知识点汇总系列——Android
  3. Android共享动画兼容实现
  4. Android(安卓)动画之ScaleAnimation应用详解
  5. Android(安卓)多个 Activity 调用 跳转
  6. android View各属性详解
  7. Android(安卓)的 ListView 的CheckBox标题栏显示文本之后显示单
  8. android 文字图片合成
  9. 给Activity切换加入动画

随机推荐

  1. Linux 下Android 开发环境搭建
  2. (转载自diycode)2017 Android 面试题分享
  3. Maven开发Android指南 2 配置android-mav
  4. 安装|卸载apk文件在Android仿真器中
  5. android 画虚线、实线,画圆角矩形,一半圆角
  6. Android 侧滑菜单的实现
  7. Android NFC架构分析
  8. android EditText设置文字选中
  9. Android 获取状态栏的高度
  10. Android(安卓)Animation总结