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();
}
}