Android动画按照不同类型分为以下几种:
1.逐帧动画(frame-by-frame animation) : 几张图片进行快速的播放形成的动画
2.补间动画(tweened animation):设置初始值、结束值。中间动态由安卓完成
3.属性动画(property animation):对组件的属性进行改变,从而达到动画的效果
逐帧就是图片叠加显示效果。补间动画与属性动画有些相似,区别在于补间动画可操作属性较少,并且需要java、xml配合,属性动画对属性都能操作,java即可完成
逐帧动画(frame-by-frame animation) : 几张图片进行快速的播放形成的动画
实现逻辑:drawable下创建xml资源,通过animation-list形成动画,然后设置成一个布局(例如RelativeLayout)的背景。再通过java代码获取到动画的 Drawable资源,然后通过其start() 启动动画、stop()停止动画,可配合点击事件完成。
1.1.1、drawable下创建frame.xml,添加animation-list,animation-list添加图片。
参数:duration:一张图片显示的多少毫秒
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/frame1" android:duration="120">item>
<item android:drawable="@drawable/frame2" android:duration="120">item>
<item android:drawable="@drawable/frame3" android:duration="120">item>
<item android:drawable="@drawable/frame4" android:duration="120">item>
<item android:drawable="@drawable/frame5" android:duration="120">item>
<item android:drawable="@drawable/frame6" android:duration="120">item>
<item android:drawable="@drawable/frame7" android:duration="120">item>
<item android:drawable="@drawable/frame8" android:duration="120">item>
animation-list>
1.1.2、activity_main.xml中设置刚才的feame为background(此处使用的是RelativeLayout布局)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/frame">
RelativeLayout>
1.1.2、动画的启动和停止
a、获取动画的 Drawable资源
AnimationDrawable anim = (AnimationDrawable) relativeLayout.getBackground();
b、启动动画 :anim.start();
c、 停止动画 :anim.stop();
package com.example.thriddemo_animation_1;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
public class MainActivity extends AppCompatActivity {
private boolean flag = true; // 动画是否停止
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout relativeLayout = findViewById(R.id.rl1); //获取布局对象
AnimationDrawable anumation = (AnimationDrawable) relativeLayout.getBackground(); //获取drawable动画资源
relativeLayout.setOnClickListener(new View.OnClickListener() { //布局点击事件
@Override
public void onClick(View view) {
if (flag){
anumation.start(); //启动
flag = false;
}else {
anumation.stop(); //停止
flag = true;
}
}
});
}
}
补间动画(tweened animation): 设置初始值、结束值。中间动态由安卓完成。
例如:图片设置初始透明度为0%,结束为100%.画面播放则是由0——100渐变,由安卓补间动画完成
1、 alpha 透明度
2、 rotate 旋转
3.、scale 缩放
4、 translate 平移
设置透明度起始为0,结束为1,5秒完成变化
android:duration=“5000”
android:fromAlpha=“1”
android:toAlpha=“0”
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:duration="5000"
android:fromAlpha="1"
android:toAlpha="0">
alpha>
set>
起始为0位置不变,最终为360,则旋转360度, pivotx、pivotY设置旋转锚点
android:duration=“5000”
android:fromDegrees=“0”
android:pivotX=“50%”
android:pivotY=“50%”
android:toDegrees=“360”
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="5000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">rotate>
set>
起始xy轴都是1,不缩放,最后为0.5,则缩放0.5。 pivotx、pivotY设置锚点
android:duration=“5000”
android:fromXScale=“1”
android:fromYScale=“1”
android:pivotX=“50%”
android:pivotY=“50%”
android:toXScale=“0.5”
android:toYScale=“0.5”
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="5000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5">scale>
set>
初始xy都是0,位置不变,最后xy都移动400dp,2秒完成
android:duration=“4000”
android:fromXDelta=“0”
android:fromYDelta=“0”
android:toXDelta=“300”
android:toYDelta=“300”
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="4000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="300"
android:toYDelta="300">translate>
set>
对要进行改变的组件,设置点击事件。然后点击事件中通过 加载xml动画设置文件来创建一个Animation对象
通过加载xml动画设置文件来创建一个Animation对象
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);
然后通过startAnimation(),启动设置的动画(参数为创建的Animation动画对象)
imgView.startAnimation(animation); //启动设置的动画
完整Java代码如下,可根据不同类型,改变注释(透明度、旋转…)
package com.example.thriddemo_animation_2;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imgView = findViewById(R.id.iv);
imgView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//通过加载xml动画设置文件来创建一个Animation对象
//1、透明度demo
//Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);
//2、旋转demo
//Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate);
//3、缩放demo
//Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale);
//4、平移demo
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate);
imgView.startAnimation(animation); //启动设置的动画
}
});
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv"
android:layout_width="300dp"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:src="@drawable/img2"
>ImageView>
LinearLayout>
属性动画,即对组件的属性进行改变,从而达到动画的效果。(例如,透明度属性从0-1.0渐变)
主要通过 ValueAnimator或ObjectAnimator,然后可选择性地配合监听器完成。
ValueAnimator anim = valueAnimator.ofFLoat(of,1f);
anim.setDuration(2000); //设置动画完成事件
anim.addUpdateListener(new valueAnimator.AnimatorupdateListener() {
@override
public void onAnimationupdate(valueAnimator animation){
xxxxxxxx…
Log.e(“leo”,"onAnimationUpdate: "+ valueAnimator.getAnimatedValue());
}
});
anim.start(); //启动ValueAnimator
ObjectAnimator继承自ValueAnimator,它可直接针对对象,可对对象的属性进行改变(通过get,set方法)
ObjectAnimator.ofFLoat(textview,propertyName: “alpha”, …values:of,1f);
先通过上面的方法设置组件的效果,如上即为:设置textview组件的属性alpha,从0变为1。该方法返回ObjectAnimator对象。
然后可objectAnimator.setDuration(4000)设置动画完成时长。
最后objectAnimator.start();启动动画
package com.example.thirddemo_animation_3;
import androidx.appcompat.app.AppCompatActivity;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ObjectAnimator
TextView textView = findViewById(R.id.tv);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
objectAnimator.setDuration(4000);
objectAnimator.start();
}
}
效果是启动时,"Hello World!"先不可见,然后逐渐透明度增高,变为可见。
动画在诞生到生效,最后到结束过程中,有时候不同阶段需要做不同事情,可对其进行监听。其主要通过 objectAnimator.addListener() 方法实现。
而在该方法中,可new Animator.AnimatorListener() 创建实现类,其实现的是AnimatorListener接口,重写会包含如下方法
onAnimationStart() 动画开始的时候调用
onAnimationEnd() 动画结束的时候调用
onAnimationCancel() 动画被取消的时候调用
onAnimationRepeat() 动画重复执行的时候调用
使用AnimatorListener需要全部方法重写,但是对于个别方法的使用,可采用抽象类AnimatorListenerAdapter,该类实现了AnimatorListener接口。
AnimatorListener
//监听器
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) { //动画开始时使用
}
@Override
public void onAnimationEnd(Animator animator) { //动画开始时使用
}
@Override
public void onAnimationCancel(Animator animator) { //动画被取消时使用
}
@Override
public void onAnimationRepeat(Animator animator) { //动画重复执行时使用
}
});
AnimatorListenerAdapter
//适配的方式,即不实现接口,而是实现其抽象类,然后可选择行的进行方法的重写
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.e("leo","onAnimationStart");
}
});
整个属性动画的java代码如下:
package com.example.thirddemo_animation_3;
import androidx.appcompat.app.AppCompatActivity;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ValueAnimator
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Log.e("leo","onAnimationUpdate: "+ valueAnimator.getAnimatedValue());
}
});
valueAnimator.start();
//ObjectAnimator
TextView textView = findViewById(R.id.tv);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
objectAnimator.setDuration(4000);
objectAnimator.start();
//监听器
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) { //动画开始时使用
}
@Override
public void onAnimationEnd(Animator animator) { //动画开始时使用
}
@Override
public void onAnimationCancel(Animator animator) { //动画被取消时使用
}
@Override
public void onAnimationRepeat(Animator animator) { //动画重复执行时使用
}
});
//适配的方式,即不实现接口,而是实现其抽象类,然后可选择行的进行方法的重写
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.e("leo","onAnimationStart");
}
});
}
}