动画Animation

1.android系统中动画框架分为:传统的view动画框架和Android 3.0推出的属性动画框架。
View动画框架又包括Tween补间动画和Frame逐帧动画

2.补间动画 TweenAnimation : 分成AlphaAnimation, RotateAnimation, ScaleAnimation, TranslateAnimation

(1)AlphaAnimation
创建alpha文件,在这个目录下src/main/res/anim/alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
    android:id="@+id/ll_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="透明"
        android:onClick="alphaClick"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="缩放"
        android:onClick="scaleClick" />
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:maxLines="1"
        android:text="位移"
        android:onClick="translateClick"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="旋转"
        android:onClick="rotateClick"/>
    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="还原"
        android:onClick="reset"/>
</LinearLayout>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/ll_container"
    android:id="@+id/image"
    android:src="@mipmap/ic_launcher"/>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ImageView imageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = findViewById(R.id.image);
}

@Override
protected void onDestroy() {
    super.onDestroy();
}

public void  alphaClick(View view){
    //加载xml中的动画
    Animation alphaAnimation = AnimationUtils.loadAnimation(this,R.anim.alpha);
    //动画运行完成保持结束的状态
    alphaAnimation.setFillAfter(true);
    imageView.startAnimation(alphaAnimation);
}

public void reset(View view){
    //移除所有动画
    imageView.clearAnimation();
 }
}

(2)ScaleAnimation 接着上面的布局和java文件
创建src/main/res/anim/scale.xml

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5"/>

MainActivity.java中加入如下方法:

public void scaleClick(View view){
   Animation scaleAnimation = AnimationUtils.loadAnimation(this,R.anim.scale);
   scaleAnimation.setFillAfter(true);
   imageView.startAnimation(scaleAnimation);
}

(3)TranslateAnimation 接着上面的布局和java文件
创建src/main/res/anim/translate.xml

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

MainActivity.java中加入如下方法:

public void translateClick(View view){
   Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate);
   animation.setFillAfter(true);
   imageView.startAnimation(animation);
}

(4)RotateAnimation 接着上面的布局和java文件
创建src/main/res/anim/rotate.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromDegrees="0"
android:pivotY="50%"
android:pivotX="50%"
android:toDegrees="+360">
</rotate>

MainActivity.java中加入如下方法:

public void rotateClick(View view){
   Animation animation = AnimationUtils.loadAnimation(this,R.anim.rotate);
   animation.setFillAfter(true);
   imageView.startAnimation(animation);
}

3.逐帧动画
一系列图片按照一定的顺序展现的过程,逐帧动画可以定义在xml中,也可以定义在Java中。
如果定义在xml中,可以放置在res/anim或res/drawable目录中(filename.xml),文件名可以作为资源id在代码中引用;如果完全由编码实现,需要使用到AnimationDrawable对象。
(1)xml定义格式

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"      //animation-list根元素
     android:oneshot=["false"|"true"]>      //true表示动画只执行一次
     <item android:drawable="@[package:]drawable/drawable_resource_name" 
           android:duration="integer"/>     //持续时间,整数 ms
</animation-list>

示例如下:
首先在drawable下创建frame.xml文件

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/f1" android:duration="500"/>
    <item android:drawable="@drawable/f2" android:duration="500"/>
    <item android:drawable="@drawable/f3" android:duration="500"/>
    <item android:drawable="@drawable/f4" android:duration="500"/>
    <item android:drawable="@drawable/f5" android:duration="500"/>
</animation-list>

res/layout/activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

 <ImageView
     android:layout_width="match_parent"
     android:layout_height="0dp"
     android:layout_weight="1"
     android:id="@+id/image"/>
 <Button
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="stopFrame"
     android:onClick="stopFrame"/>
 <Button
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="runFrame"
     android:onClick="runFrame"/>
</LinearLayout>

FrameActivity.java

public class FrameActivity extends AppCompatActivity {
private ImageView image;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_frame);
    image = findViewById(R.id.image);
    image.setImageResource(R.drawable.frame);
}

public void runFrame(View view){
    //获取image显示的图片,此时已被编译成AnimationDrawable
    AnimationDrawable anim = (AnimationDrawable) image.getDrawable();
    anim.start();  //开始动画
}

public void stopFrame(View view){
    AnimationDrawable anim = (AnimationDrawable)image.getDrawable();
    if (anim.isRunning()){   //如果正在运行,就停止
        anim.stop();
    }
 }
}

注意 :oncreate()中不能调用AnimationDrawable的start()方法,以为窗口对象还没有完全初始化,AnimationDrawable不能完全追加到窗口window对象中。如果希望程序运行就自动播放帧动画,需要把代码放在onWindowFocusChanged()方法中,当activity展示给用户时,onWindowFocusChanged就会被调用,此时实现动画效果。

(2)纯java代码启动帧动画

public class FrameActivity extends AppCompatActivity {
private ImageView image;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_frame);
    image = findViewById(R.id.image);
    //将动画资源文件设置为ImageView显示的图片
    // image.setImageResource(R.drawable.frame);
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    //完全编码实现的动画效果
    AnimationDrawable anim = new AnimationDrawable();
    for (int i =1; i<=5 ; i++){
        //根据资源名称和目录获取获取R.java中对应的资源id
        int id = getResources().getIdentifier("f"+i,"drawable",getPackageName());
        //根据资源id获取到drawable对象
        Drawable drawable =getResources().getDrawable(id);
        anim.addFrame(drawable,500);
    }
    anim.setOneShot(false);
    image.setImageDrawable(anim);
    anim.start();
 }
}

4.属性动画
能实现所有view框架能实现的动画效果和无法实现的动画效果,也可以定义xml或者直接通过Java代码实现。定义的xml文件放在res/animator文件夹下。
利用属性动画实现补间动画中透明度,位移,旋转,缩放的示例如下,布局不变,java代码如下:

public class MainActivity extends AppCompatActivity {
private ImageView imageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = findViewById(R.id.image);
}

@Override
protected void onDestroy() {
    super.onDestroy();
}

public void  alphaClick(View view){
    ObjectAnimator.ofFloat(imageView,"alpha",1,0,1)
            .setDuration(2000).start();

}

public void reset(View view){
    //移除所有动画
    // imageView.clearAnimation();
}

public void scaleClick(View view){
    AnimatorSet animatorSet = new AnimatorSet();
    imageView.setPivotX(imageView.getWidth()/2);
    imageView.setPivotY(imageView.getHeight()/2);
    animatorSet.playTogether(
            ObjectAnimator.ofFloat(imageView,"scaleX",1,0,1)
                    .setDuration(5000),
            ObjectAnimator.ofFloat(imageView,"scaleY",1,0,1)
                    .setDuration(5000)
    );
    animatorSet.start();
}

public void translateClick(View view){
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.playTogether(
            ObjectAnimator.ofFloat(imageView,"translationX",20,100,0)
                    .setDuration(2000),
            ObjectAnimator.ofFloat(imageView,"translationY",20,100,0)
                    .setDuration(2000)
    );
    animatorSet.start();
}

public void rotateClick(View view){
    imageView.setPivotX(imageView.getWidth()/2);
    imageView.setPivotY(imageView.getHeight()/2);
    ObjectAnimator.ofFloat(imageView,"rotation",0,360)
            .setDuration(1000).start();
 }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章