Android JDK为我们提供了4种动画效果,分别是:
AlphaAnimation 透明度动画效果
ScaleAnimation 缩放动画效果
TranslateAnimation 位移动画效果
RotateAnimation 旋转动画效果
以下对四种效果做测试:
1 Activity 代码
package com.example.layoutproperty;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* 动画测试 的Activity
* @author root
* 问题:1 每次动画执行完成image会回到原来位置 需要设置: setFillAfter(true);
* 2 动画停留在了结束位置的时候会闪一下子: 解决:需要每次执行完成清除动画,并且用layout重新布局image
* 3 2中的方法处理的时候动画结束,image还会闪一下才停留:解决:需要单独开启一个线程来处理
* 4 主线程中调用clearAnimation和cancelAnimation都会调用监听器中的动画End方法导致这个方法调用两次:解决:用handler来处理就不会执行两次,原因不知道为什么
* 5 按钮执行动画的时候,如果每次new一个动画去执行,则会导致一次执行多个动画
*
*
*/
public class AnimationActivity extends Activity {
AnimationSet animationSet = new AnimationSet(true);
ImageView image ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation);
Button startBtn = (Button) findViewById(R.id.startBtn);
Button endBtn = (Button) findViewById(R.id.endBtn);
image = (ImageView) findViewById(R.id.img);
startBtn.setOnClickListener(new BtnListener());
endBtn.setOnClickListener(new BtnListener());
// /取得屏幕信息
getScreen() ;
// addTranslateAnimation();
// addAlphaAnimation();
// addScaleAnimation();
// addRotateAnimation();
//
// Log.i("Animation==","执行动画开始");
// animationSet.setDuration(3000); //设置动画持续时间
// animationSet.setRepeatCount(2); //设置重复次数
// animationSet.setRepeatMode(Animation.REVERSE); //反方向执行
// image.setAnimation(animationSet); //设置动画效果
// animationSet.setFillAfter(true);
// animationSet.startNow(); //启动动画
// animationSet.getAnimations().size();
}
public void getScreen(){
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
Log.i("Animation==", "屏幕的宽高:"+dm.widthPixels+" "+dm.heightPixels) ;
}
/**
float fromXDelta 动画开始的点离当前View X坐标上的差值
float toXDelta 动画结束的点离当前View X坐标上的差值
float fromYDelta 动画开始的点离当前View Y坐标上的差值
float toYDelta 动画开始的点离当前View Y坐标上的差值
*/
private void addTranslateAnimation(){
TranslateAnimation translateAnimation=new TranslateAnimation(0,100,0,0);
// translateAnimation.setDuration(1000);
// image.setAnimation( translateAnimation );
// translateAnimation.startNow();
animationSet.addAnimation(translateAnimation );
}
// 透明度的变化
/**
fromAlpha:开始时刻的透明度,取值范围0~1。
toAlpha:结束时刻的透明度,取值范围0~1。
0.0是完全透明,1.0完全不透明。
*/
private void addAlphaAnimation(){
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
animationSet.addAnimation(alphaAnimation );
}
/**
fromX:起始X坐标上的伸缩尺寸。 个人理解值为X方向从原来对象的几倍变化到几倍大小 ,如(0.5f, 3f)从0.5倍大小变化到3倍大小
toX:结束X坐标上的伸缩尺寸。
fromY:起始Y坐标上的伸缩尺寸。个人理解值为Y方向从原来对象的几倍变化到几倍大小 ,如(1, 0.5f)从1倍大小变化到0.5倍大小
toY:结束Y坐标上的伸缩尺寸。
pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotXValue:X坐标的伸缩值。
pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotYValue:Y坐标的伸缩值
pivotXValue和pivotYValue:个人理解就是X和Y以哪个轴为中心变化,值的取值范围都为0-1
如:RELATIVE_TO_SELF: X 0为最左边 1为最右边 0.5为对象中直线 变化 ,Y的变化一样 0为最上面 0.5 为对象Y方向的中心
ABSOLUTE:绝对位置 :当X值为100f时候,则变化的x轴为100f,Y值为20f则变化的Y轴为20f的位置
RELATIVE_TO_PARENT
*/
private void addScaleAnimation(){
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 2f, 1, 2f,
Animation.RELATIVE_TO_PARENT, 0.2f,
Animation.RELATIVE_TO_PARENT, 0f);
animationSet.addAnimation(scaleAnimation );
}
//旋转特效
/**
fromDegrees:旋转的开始角度。
toDegrees:旋转的结束角度。
pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotXValue:X坐标的伸缩值。
pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotYValue:Y坐标的伸缩值。
*/
private void addRotateAnimation(){
RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_PARENT, 0f,
Animation.RELATIVE_TO_PARENT, 0.3f);
animationSet.addAnimation(rotateAnimation );
}
class BtnListener implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.startBtn:
if(animationSet.getAnimations().size()==0){
// addTranslateAnimation();
// addAlphaAnimation();
// addScaleAnimation();
addRotateAnimation();
Log.i("Animation==","执行动画开始");
animationSet.setDuration(2000); //设置动画持续时间
//animationSet.setRepeatCount(1); //设置重复次数
//animationSet.setRepeatMode(Animation.REVERSE); //反方向执行
image.setAnimation(animationSet);
animationSet.setFillAfter(true); // 则会停留在动画结束的状态
image.setAnimation(animationSet); //设置动画效果
animationSet.setAnimationListener( new MyAnimationListener() );
}
image.startAnimation(animationSet);
//animationSet.startNow(); //启动动画
Log.i( "Animation==", "动画个数:"+ animationSet.getAnimations().size() );
LinearLayout layout = (LinearLayout) image.getParent();
Log.i( "Animation==", "父容器的宽高:"+ layout.getWidth()+" "+layout.getHeight() );
break;
case R.id.backBtn:
Log.i("Animation==","执行动画返回"); //启动动画
break;
default:
Log.i("Animation==","执行动画结束按钮");
//结束动画按钮
animationSet.cancel(); //取消动画执行
break;
}
}
}
class MyAnimationListener implements AnimationListener{
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
// int[] position = new int[2];
// image.getLocationInWindow(position);
Log.i("Animation: ", "getLocationInWindow start1 :" + image.getLeft() + "," + image.getTop() );
// Log.i("Animation: ", "getLocationInWindow start2:" + position[0] + "," + position[1] );
}
@Override
public void onAnimationEnd(Animation animation) {
Log.i("Animation: ", "getLocationInWindow end3======== :" );
new Thread(){
@Override
public void run() {
//handler.sendEmptyMessage(1);
}
}.start();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
//平移动画结束时,让对象停留在平移的位置
Handler handler = new Handler(){
public void handleMessage(Message msg) {
Log.i("Animation: ", "getLocationInWindow end2 :" + image.getLeft() + "," + image.getTop() );
int left = image.getLeft() +100;//+(int)(p2-p1); 100 为每次平移的距离
int top = image.getTop() ;
int width = image.getWidth();
int height = image.getHeight();
image.clearAnimation();
image.layout(left, top, left+width, top+height);
}
};
}
2 xml代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/startBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始动画"/> <Button android:id="@+id/endBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="结束动画"/> <Button android:id="@+id/backBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="返回动画"/> <ImageView android:id="@+id/img" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/ic_launcher"/> </LinearLayout>