浅谈Android视图动画
简要说明
Android视图动画类中AlaphAnimation,RotateAnimation,TranslateAnimation,ScaleAnimation四个基本动画类,除了第一个外,余下三个类的构造方法都会使用的到如下三个变量值:
1.Animation.ABSOLUTE;//View绝对的位置变化
2.Animation.RELATIVE_TO_SELF;//View相对于自身的位置变化
3.Animation.RELATIVE_TO_PARENT;//View相对于父容器的位置变化
说明一下:无论是1.2.3哪一种View的动画坐标系都是视图坐标系,他都是以自身顶部左上角为(0,0)起始坐标点,计算所有动画起始点和结束点坐标,以及位移大小,旋转中心点,缩放中心;看下图效果;
这样说可能还是有点模糊,我们通过代码来演示更能说明问题;首先我们看看一下代码运行的效果;
在图中平移/旋转/缩放都分别使用了三种不同的位置变化模式;
TranslateAnimation(平移动画)
先看三种平移动画的代码,都是使用控件从左上角平移到左下角;
使用 ABSOLUTE
int w1 = v.getWidth();//Button控件的宽度
int h1 = v.getHeight();//Button控件的高度
/**
*这里使用ABSOLUTE,说明位移是绝对的变化;
*控件View在x方向从0变化到w1;在y方向从0变化到h1,构造方法参数值如下所示
*起始点坐标(0,0)
*结束点坐标(w1,h1)
*正好移动了v的长度和宽度
*/
TranslateAnimation t1 = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, w1,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, h1);
t1.setDuration(1000);
v.startAnimation(t1);
使用 RELATIVE_TO_PARENT
int w2 = v.getWidth();//Button控件的宽度
int h2 = v.getHeight();//Button控件的高度
float xRatio = w2 * 1.0f / mScreenWidth;//计算控件的宽度占父控件的宽度的比率
float yRatio = h2 * 1.0f / mScreenHeight;//计算控件的高度度占父控件的宽度的比率
/**
*这里使用RELATIVE_TO_PARENT,说明位移是相对于父控件的变化;
*控件View在x方向从0变化到xRatio;在y方向从0变化到yRatio,构造方法参数值如下所示
*起始点坐标 (mScreenWidth*0,mScreenHeight*0)
*结束点坐标 (mScreenWidth*xRatio,mScreenHeight*yRatio)
*看看这样一算是不是恰好移动了v的长度和宽度
*/
TranslateAnimation t2 = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, xRatio,
Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, yRatio);
t2.setDuration(1000);
v.startAnimation(t2);
使用 RELATIVE_TO_SELF
/**
*这里使用RELATIVE_TO_SELF,说明位移是相对于View自身的变化;
*控件View在x方向从0变化到1;在y方向从0变化到1,构造方法参数值如下所示
*起始点坐标(v.getWidth()*0,v.getHeight()*0)
*结束点坐标(v.getWidth()*1,v.getHeight()*1)
*计算出v的长度和宽度之后,得出v偏移也是自身的宽高
*/
TranslateAnimation t3 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1);
t3.setDuration(1000);
v.startAnimation(t3);
看我上面的注释,相信你已经对这三种方式理解已经了然于胸了,举一反三,缩放动画旋转动画是一个道理; 不论如何它是那种动画坐标系都是自身的顶部右上角位当其实坐标系;
RotateAnimation(旋转动画)
旋转动画 结合代码一步步分析,效果都是围绕控件左下角旋转360度
使用 ABSOLUTE
int w4 = v.getWidth();//Button控件的宽度
int h4 = v.getHeight();//Button控件的高度
/**
*这里使用ABSOLUTE,说明旋转的中心点是绝对的位置距离;
*控件View在x方向的中心点距离是w1;在y方向的中心点距离是h4,构造方法参数值如下所示
*旋转中心点的坐标(w4,h4)
*正好是v的长度和宽度
*/
RotateAnimation r1 = new RotateAnimation(0, 360,
Animation.ABSOLUTE, w4,
Animation.ABSOLUTE, h4);
r1.setDuration(1000);
v.startAnimation(r1);
使用 RELATIVE_TO_PARENT
int w5 = v.getWidth();//Button控件的宽度
int h5 = v.getHeight();//Button控件的高度
float xPivot = w5 * 1.0f / mScreenWidth;//计算控件的宽度占父控件的宽度的比率
float yPivot = h5 * 1.0f / mScreenHeight;//计算控件的高度度占父控件的宽度的比率
/**
*这里使用RELATIVE_TO_PARENT,说明旋转中心点的位置是相对于父控件来确定;
*控件View旋转的中心点在x方向是(mScreenWidth*xPivot)
*在y方向是(mScreenHeight*yPivot),构造方法参数值如下所示
*最后确定中心点的坐标(w5,h5),
*看看这样一计算恰好落在了v的左下角上面
*/
RotateAnimation r2 = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_PARENT, xPivot,
Animation.RELATIVE_TO_PARENT, yPivot);
r2.setDuration(1000);
v.startAnimation(r2);
使用 RELATIVE_TO_SELF
/**
*这里使用RELATIVE_TO_SELF,说明v旋转的中心点是是相对于View自身来确定;
*控件View中心点在x方向是(v.getWidth()*1),在y方向是(v.getHeight()*1),构造方法参数值如下所示
*中心点坐标正好了落在了v的左下角
*/
RotateAnimation r3 = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 1);
r3.setDuration(1000);
v.startAnimation(r3);
ScaleAnimation(缩放动画)
缩放动画 直接看分析吧,效果都是从0变化到1,而且是以控件自身的中心为缩放点的中心点
使用 ABSOLUTE
int w6 = v.getWidth();//Button控件的宽度
int h6 = v.getHeight();//Button控件的高度
/**
*这里使用ABSOLUTE,说明缩放的中心点是绝对的位置距离;
*下面构造方法中前面四个参数确定变化的范围是从0~1
*控件View在x方向的缩放中心点位置是w6/2;在y方向的中心点距离是h6/2,构造方法参数值如下所示
*旋转中心点的坐标(w6/2,h6/2)
*正好是v的长度和宽度各一半
*/
ScaleAnimation s1 = new ScaleAnimation(0, 1, 0, 1,
Animation.ABSOLUTE, w6 / 2,
Animation.ABSOLUTE, h6 / 2);
s1.setDuration(1000);
v.startAnimation(s1);
使用 RELATIVE_TO_PARENT
int w7 = v.getWidth();//Button控件的宽度
int h7 = v.getHeight();//Button控件的高度
float sXPivot = w7 * 1.0f / (2 * mScreenWidth);;//计算中心点宽度距离占父控件的宽度的比率
float sYPivot = h7 * 1.0f / (2 * mScreenHeight);//计算中心点的高度距离度占父控件的宽度的比率
/**
*这里使用RELATIVE_TO_PARENT,说明旋转中心点的位置是相对于父控件来确定;
*控件View缩放的中心点在x方向是(mScreenWidth*sXPivot)
*在y方向是(mScreenHeight*sYPivot),构造方法参数值如下所示
*最后确定中心点的坐标(w7/2,h7/2),
*看看这样一计算恰好落在了v的中心点
*/
ScaleAnimation s2 = new ScaleAnimation(0, 1, 0, 1,
Animation.RELATIVE_TO_PARENT, sXPivot,
Animation.RELATIVE_TO_PARENT, sYPivot);
s2.setDuration(1000);
v.startAnimation(s2);
使用 RELATIVE_TO_SELF
/**
*这里使用RELATIVE_TO_SELF,说明v缩放的中心点是是相对于View自身来确定;
*控件View中心点在x方向是(v.getWidth()*0,5),在y方向是(v.getHeight()*0.5),构造方法参数值如下所示
*中心点坐标正好了落在了v的中心点
*/
ScaleAnimation s3 = new ScaleAnimation(0, 1, 0, 1,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
s3.setDuration(1000);
v.startAnimation(s3);
上面已经很详细的分析了各种情形,希望对您有所帮助;
下面是完整代码,有兴趣可以copy看一下:
java代码:
public class MainActivity extends Activity {
private int mScreenWidth;//屏幕宽
private int mScreenHeight;//屏幕高
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScreenWidth = getResources().getDisplayMetrics().widthPixels;
mScreenHeight = getResources().getDisplayMetrics().heightPixels;
AnimOnclickListener mOnclickListener = new AnimOnclickListener();
findViewById(R.id.btn_translate_1).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_translate_2).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_translate_3).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_rotate_1).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_rotate_2).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_rotate_3).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_scale_1).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_scale_2).setOnClickListener(mOnclickListener);
findViewById(R.id.btn_scale_3).setOnClickListener(mOnclickListener);
}
private final class AnimOnclickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_translate_1://TranslateAnimation.ABSOLUTE
int w1 = v.getWidth();
int h1 = v.getHeight();
TranslateAnimation t1 = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, w1,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, h1);
t1.setDuration(1000);
v.startAnimation(t1);
break;
case R.id.btn_translate_2://TranslateAnimation.RELATIVE_TO_PARENT
int w2 = v.getWidth();
int h2 = v.getHeight();
float xRatio = w2 * 1.0f / mScreenWidth;
float yRatio = h2 * 1.0f / mScreenHeight;
TranslateAnimation t2 = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, xRatio,
Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, yRatio);
t2.setDuration(1000);
v.startAnimation(t2);
break;
case R.id.btn_translate_3://TranslateAnimation.RELATIVE_TO_SELF
TranslateAnimation t3 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1);
t3.setDuration(1000);
v.startAnimation(t3);
break;
case R.id.btn_rotate_1:
int w4 = v.getWidth();
int h4 = v.getHeight();
RotateAnimation r1 = new RotateAnimation(0, 360,
Animation.ABSOLUTE, w4,
Animation.ABSOLUTE, h4);
r1.setDuration(1000);
v.startAnimation(r1);
break;
case R.id.btn_rotate_2:
int w5 = v.getWidth();
int h5 = v.getHeight();
float xPivot = w5 * 1.0f / mScreenWidth;
float yPivot = h5 * 1.0f / mScreenHeight;
RotateAnimation r2 = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_PARENT, xPivot,
Animation.RELATIVE_TO_PARENT, yPivot);
r2.setDuration(1000);
v.startAnimation(r2);
break;
case R.id.btn_rotate_3:
RotateAnimation r3 = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 1);
r3.setDuration(1000);
v.startAnimation(r3);
break;
case R.id.btn_scale_1:
int w6 = v.getWidth();
int h6 = v.getHeight();
ScaleAnimation s1 = new ScaleAnimation(0, 1, 0, 1,
Animation.ABSOLUTE, w6 / 2,
Animation.ABSOLUTE, h6 / 2);
s1.setDuration(1000);
v.startAnimation(s1);
break;
case R.id.btn_scale_2:
int w7 = v.getWidth();
int h7 = v.getHeight();
float sXPivot = w7 * 1.0f / (2 * mScreenWidth);
float sYPivot = h7 * 1.0f / (2 * mScreenHeight);
ScaleAnimation s2 = new ScaleAnimation(0, 1, 0, 1,
Animation.RELATIVE_TO_PARENT, sXPivot,
Animation.RELATIVE_TO_PARENT, sYPivot);
s2.setDuration(1000);
v.startAnimation(s2);
break;
case R.id.btn_scale_3:
ScaleAnimation s3 = new ScaleAnimation(0, 1, 0, 1,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
s3.setDuration(1000);
v.startAnimation(s3);
break;
}
}
}
}
XML布局代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dip">
<Button
android:id="@+id/btn_translate_1"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="平移1\nABSOLUTE" />
<Button
android:id="@+id/btn_rotate_1"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:text="旋转1\nABSOLUTE" />
<Button
android:id="@+id/btn_scale_1"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="缩放1\nABSOLUTE" />
<Button
android:id="@+id/btn_translate_2"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/btn_translate_1"
android:text="平移2\nRELATIVE_TO_PARENT" />
<Button
android:id="@+id/btn_rotate_2"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_below="@id/btn_rotate_1"
android:layout_centerHorizontal="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:text="旋转2\nRELATIVE_TO_PARENT" />
<Button
android:id="@+id/btn_scale_2"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/btn_scale_1"
android:text="缩放2\nRELATIVE_TO_PARENT" />
<Button
android:id="@+id/btn_translate_3"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/btn_translate_2"
android:text="平移3\nRELATIVE_TO_SELF" />
<Button
android:id="@+id/btn_rotate_3"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_below="@id/btn_rotate_2"
android:layout_centerHorizontal="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:text="旋转3\nRELATIVE_TO_SELF" />
<Button
android:id="@+id/btn_scale_3"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/btn_scale_2"
android:text="缩放3\nRELATIVE_TO_SELF" />
</RelativeLayout>