本文是对Tween Animation动画的详解,由于变化动画有很多种方式,而且每一个动画都可以使用java代码和XML布局来实现.所以我觉得不必死记代码,只需要知道一个动画效果需要用哪种方式去实现即可.具体代码可参考如下:
在实现本文所有例子之前,你须在Android Studio res目录下右键新建一个director取名为anim 用于存放动画的XML
Demo截图如下:
闪光灯截图如下:
ListView飞入截图如下:
(1).缩放动画
XML代码如下:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:pivotX="0%"
android:pivotY="50%"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.1"
android:toYScale="0.1"
android:fillAfter="true">
<!--
scale表示缩放动画 是Tween Animation(变化动画的一种)
android:duration="2000" 表示动画播放的时间为2000毫秒(开始缩放到缩放结束) 没有代码提示
android:fromXScale="1"表示缩放之前X轴的大小(0表示完全缩放,即不可见状态,1,表示没有原来大小)
android:fromYScale="1"表示缩放之前Y轴的大小
android:toXScale="0" 表示缩放之后X轴的大小
android:toYScale="0" 表示缩放之后Y轴的大小
android:pivotX="50%", android:pivotY="50%"表示在X,Y轴上缩放的位置,
这里设置为50%,所以图片以自己的中心点缩放
android:fillAfter="ture" 表示保持缩放之后的状态
为false 表示缩放之后回复到初始状态 (没有代码提示)
-->
</scale>
Java引用动画代码如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private Button button;
private ImageView imageView;
private Animation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button1);
imageView = (ImageView) findViewById(R.id.imageView);
//得到anim目录下的XML布局动画
animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//图片播放动画
imageView.startAnimation(animation);
}
});
}
}
(2)透明度动画
XML代码如下:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0"
android:duration="2000"
android:fillAfter = "false">
<!--
alpha表示透明度动画
0.0 至 1.0之间浮点型小数 0.0表示完全透明,1.0表示不透明
android:fromAlpha=""改变之前的透明度
android:toAlpha="" 改变之后的透明度
-->
</alpha>
(3)旋转动画
XML代码如下:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:toDegrees="+360"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
<!--
rotate表示旋转动画
android:fromDegrees="",android:toDegrees=""
分别表示开始旋转时的角度和旋转的角度,
当toDegrees的值大于fromDegrees的时候逆时针旋转,
反之顺时针旋转
-->
(4)位移动画
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:duration="2000"
android:fillAfter="true">
</translate>
<!--
translate表示位移动画
android:fromXDelta="0"
android:fromYDelta="0"表示该控件的起始坐标,以左上角为坐标原点
android:toXDelta="100"
android:toYDelta="100"表示控件位移之后的坐标.
判断位移的位置可以想象数学上的坐标轴,但与数轴又有不同
数轴上是:右正左负,上正下负
屏幕上是:右正左负,上负下正
-->
(5)组合动画
XML代码如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="2000"
android:fromDegrees="0"
android:toDegrees="+360"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="100"
android:duration="2000"
android:fillAfter="true"
android:startOffset="2000">
</translate>
<!--
set在这里可以理解为一个动画的集合, 里面可以放你定义好的动画类型
需要特别注意的是:如果你想这一个动画播放完再播放下一个动画
那么android:startOffset="2000"必须大于或等于你
上一个动画的android:duration="2000" 即第二个动画的开始时间
必须大于或等于你上一个动画的播放时间,否则他们会一起播放
-->
</set>
java代码引用以上动画如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.TextView;
public class SecondActivity extends AppCompatActivity implements View.OnClickListener{
private TextView textView;
private Button b1,b2,b3,b4,b5,b6,b7;
private Animation anim;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
textView = (TextView) findViewById(R.id.textView2);
//改变透明度的按钮Button点击事件
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(this);
//旋转的Button点击事件
b2 = (Button) findViewById(R.id.button2);
b2.setOnClickListener(this);
//位移的Button点击事件
b3 = (Button) findViewById(R.id.button3);
b3.setOnClickListener(this);
//通过java代码实现组合动画
b4 = (Button)findViewById(R.id.button4);
b4.setOnClickListener(this);
//通过XML实现组合动画
b5 = (Button) findViewById(R.id.button5);
b5.setOnClickListener(this);
//通过java代码实现文字闪烁
b6 = (Button) findViewById(R.id.button6);
b6.setOnClickListener(this);
//通过java代码实现文字抖动
b7 = (Button) findViewById(R.id.button7);
b7.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//匹配各个Button的点击事件
switch (v.getId()){
//改变透明度的按钮Button点击事件
case R.id.button1:
anim = AnimationUtils.loadAnimation(this,R.anim.alpha_anim);
textView.startAnimation(anim);
break;
//旋转的Button点击事件
case R.id.button2:
anim = AnimationUtils.loadAnimation(this,R.anim.rotate_anim);
textView.startAnimation(anim);
break;
//位移的Button点击事件
case R.id.button3:
anim = AnimationUtils.loadAnimation(this,R.anim.translate_anim);
textView.startAnimation(anim);
break;
//通过java代码实现组合动画
case R.id.button4:
//首先拿到两种已经在XML里面定义好的动画
Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
final Animation anim2 = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
//设置动画监听器
anim1.setAnimationListener(new Animation.AnimationListener() {
//动画开始时会被触发
@Override
public void onAnimationStart(Animation animation) {
}
//动画结束时会被触发
@Override
public void onAnimationEnd(Animation animation) {
//在anim1动画结束后开始播放动画anim2
textView.startAnimation(anim2);
}
//动画重复是会被触发
@Override
public void onAnimationRepeat(Animation animation) {
}
});
//播放动画anim1
textView.startAnimation(anim1);
break;
//通过XML实现组合动画
case R.id.button5:
anim = AnimationUtils.loadAnimation(this,R.anim.set_anim);
textView.startAnimation(anim);
break;
//通过java代码实现文字闪烁
case R.id.button6:
//所谓的文字或者图片闪烁,实际上是透明度的快速切换,
//因此我们需要一个改变透明度的类
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f);
//设置动画播放时长
alphaAnimation.setDuration(200);
//设置动画重复次数
alphaAnimation.setRepeatCount(20);
/**
*Animation.REVERSE表示动画重复模式为逆序重复
*Animation.RESTART表示动画重复模式为正序重复
*
* 就本例改变透明度闪烁文字来说
* 正序重复:1.0-->0.0 1.0-->0.0 1.0-->0.0 1.0-->0.0
* 逆序重复:1.0-->0.0 0.0-->1.0 1.0-->0.0 0.0-->1.0
*
* 所以某些时候逆序重复的给人的感觉比较连续
*/
alphaAnimation.setRepeatMode(Animation.REVERSE);
textView.startAnimation(alphaAnimation);
break;
//通过java代码实现文字抖动
case R.id.button7:
//所谓的文字抖动,实际上是快速的短距离位移形成的效果
TranslateAnimation ta = new TranslateAnimation(-10, 10, 0, 0);
//设置动画播放时间
ta.setDuration(100);
//设置播放次数
ta.setRepeatCount(20);
//设置播放顺序(逆序播放)
ta.setRepeatMode(Animation.REVERSE);
//加载动画
textView.startAnimation(ta);
break;
}
}
}
制作闪光灯的时候你需要两张图片,一张灯亮,一张灯灭.并在制作一个选择器,组装这两张图片,然后用ImageView引用这个选择器,最后在java代码中用线程延时调用
选择器代码如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/w_warning_light_on"></item>
<item android:state_selected="false" android:drawable="@drawable/w_warning_light_off"></item>
<item android:drawable="@drawable/w_warning_light_off"></item>
</selector>
java代码如下:
package myself.myapplication;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
/**
*通过线程切换两张图片,模拟闪光灯的效果
*/
public class FlashBulb extends AppCompatActivity implements View.OnClickListener {
private Button btn1, btn2;
private ImageView imageView;
//线程间的使者
private Handler handler = new Handler();
private Runnable thread = new Runnable() {
@Override
public void run() {
//如果图片被选中了
if(imageView.isSelected()){
//反选它
imageView.setSelected(false);
}else{
imageView.setSelected(true);
}
//延时调用线程
handler.postDelayed(thread, 100);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash_bulb);
btn1 = (Button) findViewById(R.id.start);
btn1.setOnClickListener(this);
btn2 = (Button) findViewById(R.id.stop);
btn2.setOnClickListener(this);
imageView = (ImageView) findViewById(R.id.flash);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.start:
//调用线程
handler.postDelayed(thread, 100);
break;
case R.id.stop:
//删除线程
handler.removeCallbacks(thread);
break;
}
}
}
ListView飞入效果实现之前须在anim目录下定义一个组合动画,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="300"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<!--
飞入动画是位移动画和透明度动画的组合体
位移的同时ListView的每一项Item从无到有的出现
它们的动画时间必须是一致的
-->
</set>
java代码如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* 实现ListView右飞入的效果
*/
public class RightIn extends AppCompatActivity {
private ListView listView;
private ArrayAdapter adapter;
private List<String>list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_right_in);
//实例化控件
listView = (ListView) findViewById(R.id.listView);
//准备数据
list = new ArrayList<>();
for (int i = 1; i <= 20; i++) {
String s = "##########第"+i+"行##########";
list.add(s);
}
adapter = new ArrayAdapter(RightIn.this, android.R.layout.simple_list_item_1,
android.R.id.text1, list);
//视图控件加载适配器
listView.setAdapter(adapter);
//布局文件加载动画
LayoutAnimationController lac = new LayoutAnimationController(
AnimationUtils.loadAnimation(this,R.anim.right_in_anim));
/**
* ORDER_NORMAL:播放顺序为从上到下
* ORDER_REVERSE:播放顺序为从下到上
* ORDER_RANDOM:为乱序播放
*/
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
//视图控件加载布局动画
listView.setLayoutAnimation(lac);
//开始播放动画
listView.startLayoutAnimation();
}
}