在Android中,系统给我们提供了两种实现动画效果的方法,其中一种是Tween动画,还有一种是Frame动画;
1、Tween动画中,我们可以通过Tween动画去使得视图实现视图放大,缩小,旋转,渐变等等功能;这个动画类在android.view.animation包下面。
下面,我主要讲讲我们用到的系统提供以下的一些常用方法:
Animation 这是动画的抽象类,其他的几个实现的动画类继承这个类
AnimationSet这是动画的属性的集合类
AnimationUtils 这个类是定义动画工具类
AlphaAnimation 这个类可以对动画的透明度进行控制
RotateAnimation 这个类可以对动画的旋转的位置进行控制
ScaleAnimation 这个类可以对动画的大小进行控制
TranslateAnimation 这个类可以对动画位置进行控制
下面是Twwen动画的一些常用动画实现类的说明
1、AlphaAnimation 类(渐变调整透明度)
常用的构造方法
AlphaAnimation(float fromAlpha, float toAlpha)
参数说明:
float fromAlpha :动画刚开始的透明度 ,
float toAlpha:动画结束的透明度 取值范围是(0.0到1.0,;0.0代表不透明,1.0代表完全透明)
2、RoateAnimation 类 (动画旋转)
常用的构造方法
RotateAnimation(float fromDegrees, float toDegrees),
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY),
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
参数说明:
.fromDegrees:开始旋转的角度,
.toDegrees:结束旋转的角度
.pivotXType:在X坐标方向的伸缩的方式,
.pivotYType:在Y坐标方向的伸缩方式;
.pivotXValue:在X坐标方向的伸缩值,
.pivotYValue:在Y坐标方向的伸缩值
3、ScaleAnimation 类(动画大小的控制类)
常用的构造方法
ScaleAnimation(float fromX, float toX, float fromY, float toY)
ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
参数说明:
fromX: 起始的X坐标,
toX:结束的X坐标,
fromY:起始的Y坐标,
toY:结束的Y坐标
.pivotXType:在X坐标方向的伸缩的方式,
.pivotYType:在Y坐标方向的伸缩方式;
.pivotXValue:在X坐标方向的伸缩值,
.pivotYValue:在Y坐标方向的伸缩值
4、TranslateAnimation类(动画位置控制)
常用的构造方法
TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
参数说明:
fromXDelta:起始的X坐标;
toXDelta:结束的X坐标
fromYDelta:起始的Y坐标,
toYDelta:结束的Y坐标
注:要实现Twwen动画的效果,有两种办法 第一个种是直接在代码中进行设置,第二种是在XML文件进行配置;
----------------------------------------------------------------------
先来看看第一种的直接在代码中进行设置
main_activity.xml代码入下:
<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:id="@+id/test_animation" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/bg" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="100dip"> <Button android:id="@+id/alpha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alpha" /> <Button android:id="@+id/roate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="roate" /> <Button android:id="@+id/scale" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="scale" /> <Button android:id="@+id/translate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="translate" /> </LinearLayout> </LinearLayout>
MainActivity.java的代码如下:
package com.yaowen.tweenanimation; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.TranslateAnimation; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends AppCompatActivity implements View.OnClickListener { //定义四个按钮,分别对用四种的动画效果的操作 private Button alpha, roate, scale, translate; //声明一个ImageView组件 private ImageView animation_pic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化所有UI组件 alpha = (Button) findViewById(R.id.alpha); roate = (Button) findViewById(R.id.roate); scale = (Button) findViewById(R.id.scale); translate = (Button) findViewById(R.id.translate); animation_pic = (ImageView) findViewById(R.id.test_animation); //设置按钮的点击响应事件 alpha.setOnClickListener(this); roate.setOnClickListener(this); scale.setOnClickListener(this); translate.setOnClickListener(this); } @Override public void onClick(View v) { if (v == alpha) { // 创建渐变的 AlphaAnimation()构造方法中 参数要加 f 因为是浮点型的 Animation alphaAnimation = new AlphaAnimation(0.0f, 1.0f); // 设置画面渐变的时间 单位:毫秒 本实例设置为5s alphaAnimation.setDuration(5000); //alphaAnimation.setFillAfter(true); // 为图片添加效果,开始动画 animation_pic.startAnimation(alphaAnimation); Log.d("test", "test");//调试语句,可以忽略 } if (v == roate) { Animation roateAnimation = new RotateAnimation(0f, +90f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 1.0f); roateAnimation.setDuration(3000); animation_pic.startAnimation(roateAnimation); } if (v == scale) { Animation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 1.5f, Animation.RELATIVE_TO_SELF, 1.5f); scaleAnimation.setDuration(3000); animation_pic.startAnimation(scaleAnimation); } if (v == translate) { Animation translateAnimation = new TranslateAnimation(0.0f, 100.0f, 0.0f, 100.0f); translateAnimation.setDuration(3000); animation_pic.startAnimation(translateAnimation); } } }
下面,贴上运行效果图:
========下面说一下第二种在XML文件进行配置====================
如下图,在res》》》新建一个anim的文件夹,在里面新建4个xml文件用来控制动画的显示效果:
这个四个文件的代码代码如下:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:duration="3000" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:duration="6000" android:fromDegrees="0.0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:duration="3000" android:fromXScale="0.0" android:fromYScale="0.0" android:pivotX="0%" android:pivotY="100%" android:toXScale="1.0" android:toYScale="1.0" /> </set>
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="3000" android:fromXDelta="0.0" android:fromYDelta="0.0" android:toXDelta="100.0" android:toYDelta="100.0" /> </set>
接下来就是主活动类了:
@Override public void onClick(View v) { if (v == alpha) { // 使用AnimationUitls工具类进行常见动画,使用到XML配置文件 Animation alphaAnimation = AnimationUtils.loadAnimation( MainActivity.this, R.anim.base_alpha); // 为图片添加效果,开始动画 animation_pic.setAnimation(alphaAnimation); animation_pic.startAnimation(alphaAnimation); } if (v == roate) { Animation roateAnimation = AnimationUtils.loadAnimation( MainActivity.this, R.anim.base_rotate); animation_pic.setAnimation(roateAnimation); animation_pic.startAnimation(roateAnimation); } if (v == scale) { Animation scaleAnimation = AnimationUtils.loadAnimation( MainActivity.this, R.anim.base_scale); animation_pic.setAnimation(scaleAnimation); animation_pic.startAnimation(scaleAnimation); } if (v == translate) { Animation translateAnimation = AnimationUtils.loadAnimation( MainActivity.this, R.anim.base_translate); animation_pic.setAnimation(translateAnimation); animation_pic.startAnimation(translateAnimation); } }
到这里tweenAnimation就介绍结束了,效果图和上面的区别不大,就不必要再贴了,
官方定义: Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画。Frame动画可以被定义在XML文件中,也可以完全编码实现。
如果被定义在XML文件中,我们可以放置在/res下的anim或drawable目录中(/res/[anim | drawable]/filename.xml),文件名可以作为资源ID在代码中引用(这里要说明一点,在AndroidStudio中,该文件只能放在drawable文件夹里!!);如果由完全由编码实现,我们需要使用到AnimationDrawable对象。
如果是将动画定义在XML文件中的话,语法如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
注意:<animation-list>元素是必须的,并且必须要作为根元素,可以包含一或多个<item>元素;android:onshot如果定义为true的话,此动画只会执行一次,如果为false则一直循环。
<item>元素代表一帧动画,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒。
=============下面是用例子来说明问题了=========================
在原来的项目中,新建一个空白的Activity,如下图:
修改布局文件为:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <ImageView android:id="@+id/frame_image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="启动动画" /> <Button android:id="@+id/stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="停止动画" /> <Button android:id="@+id/tweenAimation" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="切换tween动画例子" /> </LinearLayout>
修改该activity的代码入下:
package com.yaowen.frameanimation; import android.content.Intent; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import com.yaowen.tweenanimation.MainActivity; import com.yaowen.tweenanimation.R; public class FrameAnimation extends AppCompatActivity { private ImageView imageView; private Button start, stop, tweenAnimation; AnimationDrawable drawable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_frame_animation); imageView = (ImageView) findViewById(R.id.frame_image); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); tweenAnimation = (Button) findViewById(R.id.tweenAimation); tweenAnimation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(FrameAnimation.this, MainActivity.class); FrameAnimation.this.startActivity(intent); } }); } @Override public void onWindowFocusChanged(boolean hasFocus) {//见下面的注解1 super.onWindowFocusChanged(hasFocus); imageView.setBackgroundResource(R.drawable.frame_config); drawable = (AnimationDrawable) imageView.getBackground(); //drawable.start(); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { drawable.start(); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { drawable.stop(); } }); } }
注解1:当我们在onCreate中调用AnimationDrawable的start方法时,窗口Window对象还没有完全初始化,AnimationDrawable不能完全追加到窗口Window对象中,那么该怎么办呢?我们需要把这段代码放在onWindowFocusChanged方法中,当Activity展示给用户时,onWindowFocusChanged方法就会被调用,我们正是在这个时候实现我们的动画效果。当然,onWindowFocusChanged是在onCreate之后被调用的
最后额效果图如下:
点击启动动画按钮后,图片就不逐帧播放,点击停止动画按钮后,就婷了!
动画效果我弄不出来,大家将就下吧!
如果在有些场合,我们需要用纯代码方式实现一个动画,我们可以这样写:
package com.yaowen.frameanimation; import android.content.Intent; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import com.yaowen.tweenanimation.MainActivity; import com.yaowen.tweenanimation.R; public class FrameAnimation extends AppCompatActivity { private ImageView imageView; private Button start, stop, tweenAnimation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_frame_animation); imageView = (ImageView) findViewById(R.id.frame_image); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); tweenAnimation = (Button) findViewById(R.id.tweenAimation); tweenAnimation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(FrameAnimation.this, MainActivity.class); FrameAnimation.this.startActivity(intent); } }); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //完全编码实现的动画效果 final AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根据资源名称和目录获取R.java中对应的资源ID int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); //根据资源ID获取到Drawable对象 Drawable drawable = getResources().getDrawable(id); //将此帧添加到AnimationDrawable中 anim.addFrame(drawable, 300); } anim.setOneShot(false); //设置为loop imageView.setBackgroundDrawable(anim); //将动画设置为ImageView背景 anim.start(); //开始动画 start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { anim.start(); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (anim.isRunning()) { anim.stop(); } } }); } }
就介绍到这里了,如果有问题,烦请在评论区里提出来大家一起解决,谢谢观看!