android 动画总结(利用属性动画做一个波浪)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010339039/article/details/50245783

一:概述

这篇博客就将动画做一个总结。平时用用view动画基本能解决挺多问题。帧动画就时像播放电影一样一帧一帧的播放。属性动画就无敌了。直接更改某个属性来达到动画,其实他能更改的不只是view,任意对象都能更改,只要对应的属性有get,set方法。

1.view动画:

这里写图片描述

view动画就只有四种变化方式,平移,缩放,透明度,旋转。

我们先看看从xml文件中写 平移 动画

view动画的xml文件必须写在res/anim目录下。

android:fromXDelta 表示x起始值
android:toXDelta 表示x结束值
android:fromYDelta 表示y的起始值
android:toYDelta 表示y的结束值
android:duration 花多少时间将动画执行完毕

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromXDelta="50.0"
    android:toXDelta="200.0"
    android:fromYDelta="0.0"
    android:startOffset="1700"
    android:toYDelta="100.0"
    android:duration="1000"
    />

然后在java代码中用以下方式加载view动画。(其他view动画都是这种方式)

 Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_translate);
 translate.startAnimation(translateAnimation);

再来看看缩放动画

android:fromXScale=”1.0” 从最开始的样子,就是本来的样子,如果>1.0就是变大,<1.0就是变小
android:toXScale=”1.4” 就是从fromXScale变到toXScale的样子。从x方向上拉伸
android:interpolator 插值器,控制动画的变化速度
android:pivotX=”0%” 是从最左边开始变化,如果是10%就是从10%*自身的宽度的地方做分割点向两边变化
android:pivotY=”100%” 是从最下面开始变化,道理同android:pivotX

xml 文件写好后,就同上面写的Java代码中加载就行了。

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromXScale="1.0"
    android:toXScale="1.4"
    android:fromYScale="1.0"
    android:toYScale="0.6"
    android:pivotX="0"
    android:pivotY="1.0"
    android:fillAfter="false"
    android:duration="700" />

然后我们再来看看旋转动画。

fromDegrees开始旋转的角度
toDegrees旋转到的角度
startOffset是延迟多少秒开始执行动画
pivotX就是以哪个点开始旋转,如果pivotX ,pivotY都是50%的话,那么就是以中心开始旋转

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="-45"
    android:pivotX="70%"
    android:pivotY="50%"
    android:startOffset="1700"
    android:duration="400"
    />

来个比较简单的透明度的动画

android:fromAlpha开始的透明度
android:toAlpha最后的透明度
android:fillAfter动画运行到最后是否停留到最后的状态。true时停留到最后状态。
android:repeatCount 重复的次数
android:repeatMode=”restart” 重复的模式 restart 就是动画结束后又从头开始
android:repeatMode=”reverse” reverse就是动画结束后重结束的状态回到开始的状态,比如 从0旋转到了10然后就又从10返回旋转到了0,0又到10,如此往复。

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0"
    android:toAlpha="1.0"
    android:fillAfter="false"
    android:duration="700"
    android:repeatCount="5"
    />

还有将多个动画一起播放的。
< set >标签就是将动画放在一起然后一起播放。

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true" >
    <translate
        android:fromXDelta="0.0"
        android:toXDelta="2000.0"
        android:fromYDelta="0.0"
        android:toYDelta="1000.0"
        android:duration="1000"
        />
    <rotate
        android:fromDegrees="0"
        android:toDegrees="-45"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000"
        />
</set>

再来看看直接在java代码中实现动画的编写。

缩放动画
ScaleAnimation 类对应的是缩放动画。
构造函数中所对应的参数从左到右分别是:
fromX 开始时x的值
toX 结束时x的值
fromY 开始时y的值
toY 结束时y的值
pivotX 缩放轴点的x坐标
pivotY 缩放轴点的y坐标

  private void getscaleAnimationFromJava(){
//        float fromX, float toX, float fromY, float toY,
//        float pivotX, float pivotY
        ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f,2f,0f,2f,0.5f,0.5f);
        scaleAnimation.setDuration(2000);
        scale.startAnimation(scaleAnimation);
    }

透明度动画:

这个就是花1s时间从完全透明变化到完全不透明

  private void getAliphaAnimationFromJava() {
        AlphaAnimation alipha = new AlphaAnimation(0.0f, 1.0f);
        alipha.setDuration(1000);
        alpha.startAnimation(alipha);
    }

位移动画:
参数从左到右分别是
fromXType 开始时x坐标的类型(下面会讲部分类型的东西)
fromXValue 开始时x坐标的值
toXType 结束时x坐标的类型
toXValue 结束时x坐标的值
fromYType 开始时y坐标的类型
fromYValue 开始时y坐标的值
toYType 结束时y坐标的类型
toYValue 结束时y坐标值

  private void getTranslateFromJava(){
       TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT,0f,
               Animation.RELATIVE_TO_PARENT,0.5f,
               Animation.RELATIVE_TO_PARENT,0f,
               Animation.RELATIVE_TO_PARENT,0.5f
               );
       translateAnimation.setDuration(2000);
       translate.startAnimation(translateAnimation);
   }

旋转动画:

构造函数的参数从左到右分别是:
fromDegrees 开始旋转的角度
toDegrees 结束是旋转的角度
pivotXType 旋转点的x坐标的类型
pivotXValue 旋转点x坐标的值
pivotYType 旋转点的y坐标的类型
pivotYValue 旋转点y坐标的值

注:来看看坐标类型那个参数
Animation.ABSOLUTE 对应的值是绝对坐标 e.g 0.5对应的就是第0.5个px
Animation.RELATIVE_TO_SELF 相对与自身的值 e.g 0.5对应的就是第0.5 * 自身的值
Animation.RELATIVE_TO_PARENT 相对的是父控件的值 e.g 0.5对应的就是0.5 * 父控件的值

private void getRotateFromJava(){
// float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
// int pivotYType, float pivotYValue
// Animation.RELATIVE_TO_SELF 相对于自身0.5*自身的宽度就是中间,Animation.ABSOLUTE如果是0.5不再是中间,而是从左边开始的0.5个px。
    RotateAnimation rotateAnimation = new RotateAnimation(0f,-100f,Animation.ABSOLUTE,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotateAnimation.setDuration(1000);
    rotate.startAnimation(rotateAnimation);
}

ok view动画就差不多这些。一般的还是够用了。

2.LayoutAnimation

先看看图:

这里写图片描述

layoutAnimation是对viewgroup设置的动画。就是对容器设置的。但是动画是作用在容器的子元素上。
这个是每个子view做的动画

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="true" >
    <translate
        android:fromXDelta="0.0"
        android:toXDelta="2000.0"
        android:fromYDelta="0.0"
        android:toYDelta="1000.0"
        android:duration="1000"
        />
    <rotate
        android:fromDegrees="0"
        android:toDegrees="-45"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="1000"
        />
</set>

android:delay 延迟多少秒

android:animation=”@anim/all_anim” 设置动画
android:animationOrder=”random” 动画执行顺序
android:delay=”30%” 设置每个子元素延迟多少执行,比如第一个延迟200ms进去的,那么第二个就是400ms开始执行。

<layoutAnimation  xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="30%"
    android:animationOrder="random"
    android:animation="@anim/all_anim" />

为listview设置动画。一般还是listview用的表较多

 <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layoutAnimation="@anim/layout_animaiton"
        android:layout_height="match_parent" />

3.帧动画

这个文件写在drawable下

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item
        android:drawable="@drawable/ic_launcher"
        android:duration="200" />
    <item
        android:drawable="@drawable/cou"
        android:duration="200" />
    <item
        android:drawable="@drawable/mingzi"
        android:duration="200" />
</animation-list>

这里写图片描述
不要在oncreate方法中启动这个帧动画,因为还没有完全attach到window上,如果想已开启就开始这个动画。就在onWindowFocusChanged(boolean) 中调用。

public class DrawableAnimationActivity extends AppCompatActivity {
    private AnimationDrawable rocketAnimation;
    private ImageView img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_drawable_animation);
        img = (ImageView) findViewById(R.id.img);
        img.setBackgroundResource(R.drawable.drawable_animation);
        rocketAnimation = (AnimationDrawable) img.getBackground();
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                rocketAnimation.start();
            }
        });
    }

}

4.属性动画:

我利用属性动画,做了一个波浪。(利用三角函数)

这里写图片描述

属性动画应该是无所不能的。

属性动画可以对任意对象的属性进行动画而不仅仅是view,动画默认时间间隔时300ms,默认帧率是10ms/s。效果是:在一个时间间隔内完成对象从一个属性值到另一个属性值的改变。属性动画时在Android 3.0才开始有的。但是兼容以前的话可以利用nineoldandroids来兼容。但是nineoldandroids是view动画上建立的。所以本质还是view动画。

下面来看看这个波浪的实现细节吧。

因为这里面的曲线全是由200段直线组合成的。所以需要找到200个点。
这个波浪中只有一个波峰或者一个波谷,所以x方向上的坐标选了一个区间就是(offset,offset+PI)
这个区间被分成了200份,分别求出对应的y值,就做出了200个坐标,然后依次连接成线。然后再不断改变offset的值,然后invalide不断重绘就可以形成动画。
这里写图片描述
offset属性必须实现对应的get,set函数。

 public int getOffset() {
        return offset;
    }

    public void setOffset(int offset) {
        this.offset = offset;
        getPoint();
    }

利用ObjectAnimator 将offset从0变道50用时10s

ObjectAnimator 是下面要讲到的ValueAnimator的子类。

   private void objectJava(){
        ObjectAnimator sin = ObjectAnimator.ofInt(sinView, "offset", 0, 50);
        sin.setDuration(10000);
        sin.start();
    }

再看看利用来制作动画ValueAnimator,ValueAnimator这个不作用在某个对象上。
ValueAnimator.ofInt(0,10)。
value.setDuration(10000)
花时10s将值0变到10,但是没说把哪个对象的哪个值变化。
int currentValue = (Integer) animation.getAnimatedValue();
sinView.setOffset(currentValue);
在回调中自己调用

 private void valueJava(){
        ValueAnimator value = ValueAnimator.ofInt(0,10);
        value.setDuration(10000);
        value.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = (Integer) animation.getAnimatedValue();
                sinView.setOffset(currentValue);

            }
        });
        value.start();

    }

5.插值器

直接看看图吧。

这里写图片描述

源码下载

参考书籍

《Android开发艺术探索》

加个好友共同学习(不是公众号):

这里写图片描述

因为小弟水平有限,如果有写的有问题,希望指出。

猜你喜欢

转载自blog.csdn.net/u010339039/article/details/50245783