Android动画
1、动画的理解和使用
Android 动画分类
总的来说,Android动画可以分为两类,最初的传统动画和Android3.0 之后出现的属性动画
;传统动画又包括 帧动画(Frame Animation)
和补间动画(Tweened Animation)
。
1.1、逐帧动画
1.1.1、 定义
帧动画是最容易实现的一种动画,这种动画更多的依赖于完善的UI资源,他的原理就是将一张张单独的图片连贯的进行播放,从而在视觉上产生一种动画的效果;有点类似于某些软件制作gif动画的方式。
- 帧动画是顺序播放一组预先定义好的图片,不同于动画,系统提供了另外一个类AnimationDrawable来使用帧动画。
1.1.2、 使用方式
方式1
-
1、准备图片资源:将图片资源放在drawable-hdpi目录下;
-
2、在drawable目录下新建animation-list类型文件:
frame_anim.xml
-
3、在布局文件中,添加ImageView,将其background属性设置为动画资源xml:
activity_main.xml
- 也可以在代码中动态设置
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/frame_anim" />
- 4、java中,获取动画资源,调用start( )开启动画,stop( )停止动画
frame_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" >
<!-- animation-list 帧动画 -->
<!-- android:oneshot的值为 false代表播放多次,true代表只播放一次 -->
<!-- duration代表每张图片的播放时间 ,定义一个持续时间为50毫秒的动画帧 -->
<item
android:drawable="@drawable/img00"
android:duration="50"/>
<item
android:drawable="@drawable/img01"
android:duration="50"/>
<item
android:drawable="@drawable/img02"
android:duration="50"/>
<item
android:drawable="@drawable/img03"
android:duration="50"/>
<item
android:drawable="@drawable/img04"
android:duration="50"/>
<item
android:drawable="@drawable/img05"
android:duration="50"/>
<item
android:drawable="@drawable/img06"
android:duration="50"/>
<item
android:drawable="@drawable/img07"
android:duration="50"/>
<item
android:drawable="@drawable/img08"
android:duration="50"/>
<item
android:drawable="@drawable/img09"
android:duration="50"/>
<item
android:drawable="@drawable/img10"
android:duration="50"/>
<item
android:drawable="@drawable/img11"
android:duration="50"/>
<item
android:drawable="@drawable/img12"
android:duration="50"/>
<item
android:drawable="@drawable/img13"
android:duration="50"/>
<item
android:drawable="@drawable/img14"
android:duration="50"/>
<item
android:drawable="@drawable/img15"
android:duration="50"/>
<item
android:drawable="@drawable/img16"
android:duration="50"/>
<item
android:drawable="@drawable/img17"
android:duration="50"/>
<item
android:drawable="@drawable/img18"
android:duration="50"/>
<item
android:drawable="@drawable/img19"
android:duration="50"/>
<item
android:drawable="@drawable/img20"
android:duration="50"/>
<item
android:drawable="@drawable/img21"
android:duration="50"/>
<item
android:drawable="@drawable/img22"
android:duration="50"/>
<item
android:drawable="@drawable/img23"
android:duration="50"/>
<item
android:drawable="@drawable/img24"
android:duration="50"/>
</animation-list>
根节点是animation-list(动画列表),里面有一个或者多个item节点组成,oneshot属性表示是否只播放一次,true表示只会播放一次,false表示一直循环播放,内部用item节点声明一个动画帧,android:drawable指定此帧动画所对应的图片资源,android:druation代表此帧持续的时间,整数,单位为毫秒
在activity_main中添加控件
<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"
tools:context="com.havorld.frameanimation.MainActivity" >
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<!-- android:background="@drawable/frame_anim" -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:padding="10dp" >
<Button
android:id="@+id/start"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放" />
<Button
android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止" />
</LinearLayout>
</RelativeLayout>
在代码中获取并开启帧动画
public class MainActivity extends Activity implements OnClickListener {
private ImageView imageView;
private AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
findViewById(R.id.start).setOnClickListener(this);
findViewById(R.id.stop).setOnClickListener(this);
setXml2FrameAnim1();
// setXml2FrameAnim2();
}
/**
* 通过XML添加帧动画方法一
*/
private void setXml2FrameAnim1() {
// 把动画资源设置为imageView的背景,也可直接在XML里面设置
imageView.setBackgroundResource(R.drawable.frame_anim);
animationDrawable = (AnimationDrawable) imageView.getBackground();
}
/**
* 通过XML添加帧动画方法二
*/
private void setXml2FrameAnim2() {
// 通过逐帧动画的资源文件获得AnimationDrawable示例
animationDrawable = (AnimationDrawable) getResources().getDrawable(
R.drawable.frame_anim);
imageView.setBackground(animationDrawable);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
if (animationDrawable != null && !animationDrawable.isRunning()) {
animationDrawable.start();
}
break;
case R.id.stop:
if (animationDrawable != null && animationDrawable.isRunning()) {
animationDrawable.stop();
}
break;
default:
break;
}
}
}
AnimationDrawable 几个常见的api
void start() - 开始播放动画
void stop() - 停止播放动画
addFrame(Drawable frame, int duration) - 添加一帧,并设置该帧显示的持续时间
void setOneShoe(boolean flag) - false为循环播放,true为仅播放一次
boolean isRunning() - 是否正在播放
方式2
通过代码实现帧动画
/**
* 通过代码添加帧动画方法
*/
private void setSrc2FrameAnim() {
animationDrawable = new AnimationDrawable();
// 为AnimationDrawable添加动画帧
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img00), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img01), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img02), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img03), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img04), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img05), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img06), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img07), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img08), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img09), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img10), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img11), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img12), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img13), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img14), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img15), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img16), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img17), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img18), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img19), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img20), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img21), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img22), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img23), 50);
animationDrawable.addFrame(
getResources().getDrawable(R.drawable.img24), 50);
// 设置为循环播放
animationDrawable.setOneShot(false);
imageView.setBackground(animationDrawable);
}
1.2、补间动画(Tweened Animation)
1.2.1、 定义
和前面学的帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!
- 原形态变成新形态时为了过渡变形过程,生成的动画就叫补间动画
补间动画的使用方式分为两种:在XML 代码 / Java 代码里设置
- 前者优点:动画描述的可读性更好
- 后者优点:动画效果可动态创建
1.2.2、补间动画的分类
根据不同的动画效果,补间动画分为4种动画:
- 平移动画(Translate)
- 缩放动画(scale)
- 旋转动画(rotate)
- 透明度动画(alpha)
同时,不同类型的动画对应于不同的子类,具体如下图:
具体说明如下:
- 1、AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应标签!
- 2、ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点,还有动画的持续时间;对应标签!
- 3、TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续时间即可;对应标签!
- 4、RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画持续时间和旋转的轴心;对应标签
- 5、AnimationSet:组合渐变,就是前面多种渐变的组合,对应标签
1.2.3、平移动画(Translate)
设置方法1:在XML 代码中设置
- 步骤1:在
res/anim
的文件夹里创建动画效果.xml
文件
此处路径为res/anim/translate.xml
- 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:
部分参数说明
<?xml version="1.0" encoding="utf-8"?>
// 采用<translate /> 标签表示平移动画
<translate xmlns:android="http://schemas.android.com/apk/res/android"
// 以下参数是4种动画效果的公共属性,即都有的属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
// 以下参数是平移动画特有的属性
android:fromXDelta="0" // 视图在水平方向x 移动的起始值
android:toXDelta="500" // 视图在水平方向x 移动的结束值
android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
android:toYDelta="500" // 视图在竖直方向y 移动的结束值
/>
注①: 数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点
- 骤3:在Java代码中创建Animation对象并播放动画
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(translateAnimation);
// 步骤3:播放动画
简单使用demo:
translate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="400"
android:toYDelta="400"
android:duration="2000" />
</set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是动画" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
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 static final String TAG = "jmw";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this
,R.anim.translate);
button.startAnimation(animation);
}
});
}
}
实验效果:
设置方法2:在 Java 代码中设置
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation translateAnimation = new TranslateAnimation(0,500,0,500);
// 步骤2:创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
// 参数分别是:
// 1. fromXDelta :视图在水平方向x 移动的起始值
// 2. toXDelta :视图在水平方向x 移动的结束值
// 3. fromYDelta :视图在竖直方向y 移动的起始值
// 4. toYDelta:视图在竖直方向y 移动的结束值
translateAnimation.setDuration(3000);
// 固定属性的设置都是在其属性前加“set”,如setDuration()
mButton.startAnimation(translateAnimation);
// 步骤3:播放动画
1.2.4、缩放动画(Scale)
设置方法1:在XML 代码中设置
- 步骤1:在
res/anim
的文件夹里创建动画效果.xml
文件
此处路径为res/anim/scale.xml
- 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:
部分参数说明
<?xml version="1.0" encoding="utf-8"?>
// 采用<scale/> 标签表示是缩放动画
<scale xmlns:android="http://schemas.android.com/apk/res/android"
// 以下参数是4种动画效果的公共属性,即都有的属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
// 以下参数是缩放动画特有的属性
android:fromXScale="0.0"
// 动画在水平方向X的起始缩放倍数
// 0.0表示收缩到没有;1.0表示正常无伸缩
// 值小于1.0表示收缩;值大于1.0表示放大
android:toXScale="2" //动画在水平方向X的结束缩放倍数
android:fromYScale="0.0" //动画开始前在竖直方向Y的起始缩放倍数
android:toYScale="2" //动画在竖直方向Y的结束缩放倍数
android:pivotX="50%" // 缩放轴点的x坐标
android:pivotY="50%" // 缩放轴点的y坐标
// 轴点 = 视图缩放的中心点
// pivotX pivotY,可取值为数字,百分比,或者百分比p
// 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
// 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。
//在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
// 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。
//在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
// 两个50%表示动画从自身中间开始,具体如下图
/>
pivot 这个属性主要是在translate 和 scale 动画中,这两种动画都牵扯到view 的“物理位置“发生变化,所以需要一个参考点。而pivotX和pivotY就共同决定了这个点;它的值可以是float或者是百分比数值。
以pivotX为例,
pivotX取值 | 含义 |
---|---|
10 | 距离动画所在view自身左边缘10像素 |
10% | 距离动画所在view自身左边缘 的距离是整个view宽度的10% |
10%p | 距离动画所在view父控件左边缘的距离是整个view宽度的10% |
pivotY 也是相同的原理,只不过变成的纵向的位置。如果还是不明白可以参考源码,在Tweened Animation中结合seekbar的滑动观察rotate的变化理解。
步骤3:在Java代码中创建Animation对象并播放动画
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(scaleAnimation);
// 步骤3:播放动画
简单使用demo:
scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0.5"
android:toYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000" />
</set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是动画" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
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 {
private static final String TAG = "jmw";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.iv);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通过加载xml动画设置文件来创建一个Animataion对象
Animation animation = AnimationUtils.loadAnimation(MainActivity.this
,R.anim.scale);
imageView.startAnimation(animation);
}
});
}
}
下面展示轴点为(50%,50%) 的情况
设置方法2:在 Java 代码中设置
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation rotateAnimation = new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
// 步骤2:创建缩放动画的对象 & 设置动画效果:缩放动画对应的Animation子类为RotateAnimation
// 参数说明:
// 1. fromX :动画在水平方向X的结束缩放倍数
// 2. toX :动画在水平方向X的结束缩放倍数
// 3. fromY :动画开始前在竖直方向Y的起始缩放倍数
// 4. toY:动画在竖直方向Y的结束缩放倍数
// 5. pivotXType:缩放轴点的x坐标的模式
// 6. pivotXValue:缩放轴点x坐标的相对值
// 7. pivotYType:缩放轴点的y坐标的模式
// 8. pivotYValue:缩放轴点y坐标的相对值
// pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
// pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
// pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
scaleAnimation.setDuration(3000);
// 固定属性的设置都是在其属性前加“set”,如setDuration()
mButton.startAnimation(scaleAnimation);
// 步骤3:播放动画
1.2.5、旋转动画(Rotate)
设置方法1:在XML 代码中设置
- 步骤1:在
res/anim
的文件夹里创建动画效果.xml
文件
此处路径为res/anim/rotate.xml
- 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:
部分参数说明
<?xml version="1.0" encoding="utf-8"?>
// 采用<rotate/> 标签表示是旋转动画
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
// 以下参数是4种动画效果的公共属性,即都有的属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
// 以下参数是旋转动画特有的属性
android:duration="1000"
android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
android:toDegrees="270" // 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
android:pivotX="50%" // 旋转轴点的x坐标
android:pivotY="0" // 旋转轴点的y坐标
// 轴点 = 视图缩放的中心点
// pivotX pivotY,可取值为数字,百分比,或者百分比p
// 设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。
//在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
// 设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。
//在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF。
// 设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。
//在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
// 两个50%表示动画从自身中间开始,具体如下图
/>
- 骤3:在Java代码中创建Animation对象并播放动画
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(translateAnimation);
// 步骤3:播放动画
简单使用demo:
rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000" />
</set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是动画" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
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 static final String TAG = "jmw";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this
,R.anim.rotate);
button.startAnimation(animation);
}
});
}
}
实验效果:
设置方法2:在 Java 代码中设置
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
// 步骤2:创建旋转动画的对象 & 设置动画效果:旋转动画对应的Animation子类为RotateAnimation
// 参数说明:
// 1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
// 2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
// 3. pivotXType:旋转轴点的x坐标的模式
// 4. pivotXValue:旋转轴点x坐标的相对值
// 5. pivotYType:旋转轴点的y坐标的模式
// 6. pivotYValue:旋转轴点y坐标的相对值
// pivotXType = Animation.ABSOLUTE:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
// pivotXType = Animation.RELATIVE_TO_SELF:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
// pivotXType = Animation.RELATIVE_TO_PARENT:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
rotateAnimation.setDuration(3000);
// 固定属性的设置都是在其属性前加“set”,如setDuration()
mButton.startAnimation(rotateAnimation);
// 步骤3:播放动画
1.2.6、透明度动画(Alpha)
设置方法1:在XML 代码中设置
- 步骤1:在
res/anim
的文件夹里创建动画效果.xml
文件
此处路径为res/anim/alpha.xml
- 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:
部分参数说明
<?xml version="1.0" encoding="utf-8"?>
// 采用<alpha/> 标签表示是透明度动画
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
// 以下参数是4种动画效果的公共属性,即都有的属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
// 以下参数是透明度动画特有的属性
android:fromAlpha="1.0" // 动画开始时视图的透明度(取值范围: -1 ~ 1)
android:toAlpha="0.0"// 动画结束时视图的透明度(取值范围: -1 ~ 1)
/>
- 骤3:在Java代码中创建Animation对象并播放动画
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(alphaAnimation);
// 步骤3:播放动画
简单使用demo:
alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000" />
</set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是动画" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
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 static final String TAG = "jmw";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this
,R.anim.alpha);
button.startAnimation(animation);
}
});
}
}
实验效果:
设置方法2:在 Java 代码中设置
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation alphaAnimation = new AlphaAnimation(1,0);
// 步骤2:创建透明度动画的对象 & 设置动画效果:透明度动画对应的Animation子类为AlphaAnimation
// 参数说明:
// 1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
// 2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)
alphaAnimation.setDuration(3000);
// 固定属性的设置都是在其属性前加“set”,如setDuration()
mButton.startAnimation(alphaAnimation);
// 步骤3:播放动画
1.2.7、组合动画
设置方法1:在XML 代码中设置
- 步骤1:在
res/anim
的文件夹里创建动画效果.xml
文件
此处路径为res/anim/conbined_view.xml
- 步骤2:根据 不同动画效果的语法 设置 不同动画参数,从而实现动画效果。平移动画效果设置具体如下:
部分参数说明
<?xml version="1.0" encoding="utf-8"?>
// 采用< Set/>标签
<set xmlns:android="http://schemas.android.com/apk/res/android">
// 组合动画同样具备公共属性
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:startOffset ="1000" // 动画延迟开始时间(ms)
android:fillBefore = “true” // 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillAfter = “false” // 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillEnabled= “true” // 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatMode= “restart” // 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:repeatCount = “0” // 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = @[package:]anim/interpolator_resource // 插值器,即影响动画的播放速度,下面会详细讲
// 组合动画独特的属性
android:shareinterpolator = “true”
// 表示组合动画中的动画是否和集合共享同一个差值器
// 如果集合不指定插值器,那么子动画需要单独设置
// 组合动画播放时是全部动画同时开始
// 如果想不同动画不同时间开始就要使用android:startOffset属性来延迟单个动画播放时间
// 设置旋转动画,语法同单个动画
<rotate
android:duration="1000"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:repeatMode="restart"
android:repeatCount="infinite"
/>
// 设置平移动画,语法同单个动画
<translate
android:duration="10000"
android:startOffset = “1000”// 延迟该动画播放时间
android:fromXDelta="-50%p"
android:fromYDelta="0"
android:toXDelta="50%p"
android:toYDelta="0" />
// 设置透明度动画,语法同单个动画
<alpha
android:startOffset="7000"
android:duration="3000"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
// 设置缩放动画,语法同单个动画
<scale
android:startOffset="4000"
android:duration="1000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5" />
// 特别注意:
// 1. 在组合动画里scale缩放动画设置的repeatCount(重复播放)和fillBefore(播放完后,视图是否会停留在动画开始的状态)是无效的。
// 2. 所以如果需要重复播放或者回到原位的话需要在set标签里设置
// 3. 但是由于此处rotate旋转动画里已设置repeatCount为infinite,所以动画不会结束,也就看不到重播和回复原位
</set>
- 骤3:在Java代码中创建Animation对象并播放动画
Button mButton = (Button) findViewById(R.id.Button);
// 步骤1:创建 需要设置动画的 视图View
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.view_animation);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
mButton.startAnimation(translateAnimation);
// 步骤3:播放动画
简单使用demo:
conbined_view.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
android:duration="3000"
android:startOffset ="1000"
android:fillBefore = “true”
android:fillAfter = “false”
android:fillEnabled= “true”
android:repeatMode= “restart”
android:repeatCount = “0”
android:interpolator = @[package:]anim/interpolator_resource
android:shareinterpolator = “true”
<rotate
android:duration="1000"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:repeatMode="restart"
android:repeatCount="infinite" />
<translate
android:duration="10000"
android:startOffset ="1000"
android:fromXDelta="-50%p"
android:fromYDelta="0"
android:toXDelta="50%p"
android:toYDelta="0" />
<alpha
android:startOffset="7000"
android:duration="3000"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<scale
android:startOffset="4000"
android:duration="1000"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.5"
android:toYScale="0.5" />
</set>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是动画" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
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 static final String TAG = "jmw";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this
,R.anim.conbined_view);
button.startAnimation(animation);
}
});
}
}
实验效果:
设置方法2:在 Java 代码中设置
Button mButton = (Button) findViewById(R.id.Button);
// 创建 需要设置动画的 视图View
// 组合动画设置
AnimationSet setAnimation = new AnimationSet(true);
// 步骤1:创建组合动画对象(设置为true)
// 步骤2:设置组合动画的属性
// 特别说明以下情况
// 因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
// 所以动画不会结束,而是无限循环
// 所以组合动画的下面两行设置是无效的
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);// 设置了循环一次,但无效
// 步骤3:逐个创建子动画(方式同单个动画创建方式,此处不作过多描述)
// 子动画1:旋转动画
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 子动画2:平移动画
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 子动画3:透明度动画
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 子动画4:缩放动画
Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale1.setDuration(1000);
scale1.setStartOffset(4000);
// 步骤4:将创建的子动画添加到组合动画里
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale1);
mButton.startAnimation(setAnimation);
// 步骤5:播放动画
1.2.8、综合案例
conbined_view.xml alpha.xm rotate.xml scale.xml translate.xml 同上面各小结案例
activity_main.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/btn_alpha"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="透明度渐变" />
<Button
android:id="@+id/btn_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="缩放渐变" />
<Button
android:id="@+id/btn_tran"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="位移渐变" />
<Button
android:id="@+id/btn_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="旋转渐变" />
<Button
android:id="@+id/btn_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="组合渐变" />
<ImageView
android:id="@+id/img_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="48dp"
android:src="@mipmap/img_face" />
</LinearLayout>
MainActivity
package com.example.buttontes;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
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 implements View.OnClickListener{
private Button btn_alpha;
private Button btn_scale;
private Button btn_tran;
private Button btn_rotate;
private Button btn_set;
private ImageView img_show;
private Animation animation = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
btn_alpha = (Button) findViewById(R.id.btn_alpha);
btn_scale = (Button) findViewById(R.id.btn_scale);
btn_tran = (Button) findViewById(R.id.btn_tran);
btn_rotate = (Button) findViewById(R.id.btn_rotate);
btn_set = (Button) findViewById(R.id.btn_set);
img_show = (ImageView) findViewById(R.id.img_show);
btn_alpha.setOnClickListener(this);
btn_scale.setOnClickListener(this);
btn_tran.setOnClickListener(this);
btn_rotate.setOnClickListener(this);
btn_set.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_alpha:
animation = AnimationUtils.loadAnimation(this,
R.anim.alpha);
img_show.startAnimation(animation);
break;
case R.id.btn_scale:
animation = AnimationUtils.loadAnimation(this,
R.anim.scale);
img_show.startAnimation(animation);
break;
case R.id.btn_tran:
animation = AnimationUtils.loadAnimation(this,
R.anim.translate);
img_show.startAnimation(animation);
break;
case R.id.btn_rotate:
animation = AnimationUtils.loadAnimation(this,
R.anim.rotate);
img_show.startAnimation(animation);
break;
case R.id.btn_set:
animation = AnimationUtils.loadAnimation(this,
R.anim.conbined_view);
img_show.startAnimation(animation);
break;
}
}
}
参考
1、https://www.jianshu.com/p/16e0d4e92bb2
2、https://www.jianshu.com/p/420629118c10
3、https://blog.csdn.net/carson_ho/article/details/72827747
4、https://www.runoob.com/w3cnote/android-tutorial-alphaanimation.html
5、https://blog.csdn.net/m0_37796683/article/details/90607428?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
6、https://www.jianshu.com/p/2f19fe1e3ca1