Android动画学习记录一(Android动画种类、补间动画和帧动画)

Android动画学习记录一(动画种类、补间动画和帧动画)

一、动画种类

Android动画主要分为分为两大类(三种):

  1. View动画:补间动画、帧动画
  2. 属性动画
    帧动画通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画,很显然,如果图片过多过大就会导致OOM
    属性动画通过动态地改变对象的属性从而达到动画效果,属性动画为API 11的新特性,在低版本无法直接使用属性动画,但是我们仍然可以通过兼容库来使用它。

二、View动画

在这里插入图片描述

View动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐近式动画,并且支持自定义。

2.1 补间动画

我们设置一个view开始和结束的位置,中间的view会自动由系统补齐。补间动画分为4种动画。

补间动画除了用于视图View平移、旋转、缩放 & 透明度外,还可以用于Activity 的切换效果(淡入淡出、左右滑动等),Fragement 的切换效果(淡入淡出、左右滑动等),视图组(ViewGroup)中子元素的出场效果(淡入淡出、左右滑动等)。

补间动画公有属性

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 = "@android:anim/accelerate_decelerate_interpolator" // 插值器,即影响动画的播放速度

android:interpolator
表示动画集合所采用的插值器,插值器影响动画的速度,非匀速动画就需要通过插值器来控制动画的播放过程,比如前200ms很慢,中间600ms很快,最后200ms又很慢。这个属性可以不指定,默认@android:anim/accelerate_decelerate_interpolator,即加速减速插值器。

平移动画(Translate)

res/anim/目录下创建xml文件

<?xml version="1.0" encoding="utf-8"?>
 <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" // 视图在水平方向x 移动的起始值
    android:toXDelta="100" // 视图在水平方向x 移动的结束值
    android:fromYDelta="0" // 视图在竖直方向y 移动的起始值
    android:toYDelta="100" // 视图在竖直方向y 移动的结束值
    /> 

<translate>标签标示平移动画,对应TranslateAnimation类,它可以使一个View在水平和竖直方向完成平移的动画效果,它的一系列属性的含义如下:

  • android:fromXDelta——表示x的起始值,比如0;
  • android:toXDelta——表示x的结束值,比如100;
  • android:fromYDelta——表示y的起始值;
  • android:toYDelta——表示y的结束值。

缩放动画(Scale)

缩放动画中有轴点的概念,举个例子,默认情况下轴点是View的中心点,这个时候在水平方向进行缩放的话会导致View向左右两个方向同时进行缩放,但是如果把轴点设为View的右边界,那么View就只会向左边进行缩放,反之则向右边进行缩放。如果设置为View的20%,30%就会改变效果。

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
	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

<scale>标签表示缩放动画,对应ScaleAnimation,它可以使View具有放大或者缩小的动画效果,它的一系列属性的含义如下:

  • android:fromXScale——水平方向缩放的起始值,比如0.5;
  • android:toXScale——水平方向缩放的结束值,比如1.2;
  • android:fromYScale——竖直方向缩放的起始值;
  • android:toYScale——竖直方向缩放的结束值;
  • android:pivotX——缩放的轴点的x坐标,它会影响缩放的效果;
  • android:pivotY——缩放的轴点的y坐标,它会影响缩放的效果。

旋转动画(Rotate)

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
	android:duration="1000"
	android:fromDegrees="0" // 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
	android:toDegrees="270" // 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
	android:pivotX="50%" // 旋转轴点的x坐标
	android:pivotY="0" // 旋转轴点的y坐标
/> 

<rotate>标签表示旋转动画,对于RotateAnimation,它可以使View具有旋转的动画效果,它的属性的含义如下:

  • android:fromDegrees——旋转开始的角度,比如0;
  • android:toDegrees——旋转结束的角度,比如180;
  • android:pivotX——旋转的轴点的x坐标;
  • android:pivotY——旋转的轴点的y坐标。

透明度动画(Alpha)

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
	
	android:fromAlpha="1.0" // 动画开始时视图的透明度(取值范围: -1 ~ 1)
	android:toAlpha="0.0"// 动画结束时视图的透明度(取值范围: -1 ~ 1)
/> 

<alpha>标签表示透明度动画,对应AlphaAnimation,它可以改变View的透明度,它的属性的含义如下:

  • android:fromAlpha——表示透明度的起始值,比如0.1;
  • android:toAlpha——表示透明度的结束值,比如1。

组合动画

<?xml version="1.0" encoding="utf-8"?>
// 采用< Set/>标签
<set xmlns:android="http://schemas.android.com/apk/res/android">

// 组合动画独特的属性
    android:shareinterpolator =true// 表示组合动画中的动画是否和集合共享同一个差值器
    // 如果集合不指定插值器,那么子动画需要单独设置

// 组合动画播放时是全部动画同时开始
// 如果想不同动画不同时间开始就要使用android:startOffset属性来延迟单个动画播放时间
/>

<set>标签表示动画集合,对应AnimationSet类,它可以包含若干个动画,并且它的内部也是可以嵌套其他动画集合。
android:shareInterpolator
表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独指定所需的插值器或者使用默认值。

小结

以上动画的在Java代码中的用法有两种


第一种:
Animation xxxxanimation = AnimationUtils.loadAnimation(this, R.anim.filename);
view.startAnimation(xxxxanimation);

第二种:
AlphaAnimation xxxxalphaAnimation = new AlphaAnimation(0,1);
xxxxalphaAnimation.setDuration(3000);
view.startAnimation(xxxxalphaAnimation);

监听动画

通过Animation的setAnimationListener方法可以给View动画添加过程监听,接口如下所示。

public static interface AnimationListener {
    void onAnimationStart(Animation animation);
    void onAnimationEnd(Animation animation);
    void onAnimationRepeat(Animation animation);
}
// 主要通过setAnimationListener()设置
Animation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        // 动画开始时回调
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        // 动画结束时回调
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        //动画重复执行的时候回调
    }
});

2.2 补间动画的特殊使用场景

Activity切换

Activity的动画切换效果存在两种方式:使用系统预设和自定义切换动画效果。

系统已经封装好的动画效果
淡入淡出:android.R.anim.fade_in、android.R.anim.fade_out
由左向右滑入:android.R.anim.slide_in_left、android.R.anim.slide_out_right

在这里插入图片描述

  • 当Activity在X轴 = -100%p时,刚好完全超出屏幕到左边(位置1)
  • 当Activity在X轴 = 0%p时,刚好完全在屏幕内(位置2)
  • 当Activity在X轴 = 100%p时,刚好完全超出屏幕到右边(位置3)

核心方法:overridePendingTransition(int enterAnim, int exitAnim)
调用时机:onCreate()finish()
参数
对于在onCreate()设置:
enterAnim:进入该Activity时的动画效果资源ID
exitAnim:进入该Activity时上一个Activity离开时的动画效果资源ID

 对于在`finish()`设置:
 `enterAnim`:进入其他Activity时 进入Activity的动画效果资源ID
`exitAnim`:进入其他Activity时 该Activity离开时的动画效果资源ID
// 具体使用
// 方式1:在onCreate()设置
@Override
public void onCreate(Bundle savedInstanceState) {
    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
    super.onCreate(savedInstanceState);
}

// 方式2:在finish()设置
@Override
public void finish() {
    super.finish();
    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}

需要特别注意的是:如果进入退出页面:一个需要动画、另外一个不需要动画,但也必须设置时间相同的、没有任何变化的动画,否则会出现黑屏。

Fragment切换

Fragment切换也有使用系统预设和自定义切换动画效果两种方式。

系统预设动画效果需要通过FragmentTransaction.setTransition(int transit)进行设置
transit参数有三种

  1. FragmentTransaction.TRANSIT_NONE:无动画
  2. FragmentTransaction.TRANSIT_FRAGMENT_OPEN:标准的打开动画效果
  3. FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:标准的关闭动画效果
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)

自定义动画效果需要通过FragmentTransaction.setCustomAnimations()设置,自定义动画效果同Activity

FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.in_from_right,R.anim.out_to_left);

视图组(ViewGroup)中子元素的出场效果(LayoutAnimation)

LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,这样当它的子元素出场时都会具有这种动画效果。

(1)为子元素指定具体的入场动画

    // res/anim/anim_item.xml
    <? xml version="1.0" encoding="utf-8"? >
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="300"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:shareInterpolator="true" >

        <alpha
          android:fromAlpha="0.0"
          android:toAlpha="1.0" />

        <translate
          android:fromXDelta="500"
          android:toXDelta="0" />

    </set>

(2)定义LayoutAnimation

// res/anim/anim_layout.xml
  <?xml version="1.0" encoding="utf-8"?>
  // 采用LayoutAnimation标签
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
  android:delay="0.5"
  android:animationOrder="normal"
  android:animation="@anim/view_animation"
  // 设置入场的具体动画效果
  // 将步骤1的子元素出场动画设置到这里
  />
  • android:delay表示子元素开始动画的时间延迟,比如子元素入场动画的时间周期为300ms,那么0.5表示每个子元素都需要延迟150ms才能播放入场动画。总体来说,第一个子元素延迟150ms开始播放入场动画,第2个子元素延迟300ms开始播放入场动画,依次类推。
  • android:animationOrder表示子元素动画的顺序,有三种选项:normal、reverserandom,其中normal表示顺序显示,即排在前面的子元素先开始播放入场动画;reverse表示逆向显示,即排在后面的子元素先开始播放入场动画;random则是随机播放入场动画。
  • android:animation为子元素指定具体的入场动画。

(3)为ViewGroup指定android:layoutAnimation属性:android:layoutAnimation= “@anim/anim_layout”。对于ListView来说,这样ListView的item就具有出场动画了,这种方式适用于所有的ViewGroup,如下所示。

方式1:xml中给ViewGroup设置android:layoutAnimation="@anim/anim_layout"属性

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="#FFFFFF"
    android:orientation="vertical" >
    <ListView
        android:id="@+id/listView1"
        android:layoutAnimation="@anim/anim_layout"
        // 指定layoutAnimation属性用以指定子元素的入场动画
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

方式2:在Java代码中

// 加载子元素的出场动画
Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_item);

// 设置LayoutAnimation的属性
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);

// 为ListView设置LayoutAnimation的属性
ListView.setLayoutAnimation(controller);

其他动画代码中的使用

Animation animation = AnimationUtils.loadAnimation(this, R.anim.filename);
textView.startAnimation(animation);

2.3 属性动画

可以看这一篇博客
https://blog.csdn.net/qq_53749266/article/details/123602913?spm=1001.2014.3001.5502

三、帧动画

在这里插入图片描述

帧动画是顺序播放一组预先定义好的图片,类似于电影播放。不同于View动画,系统提供了另外一个类AnimationDrawable来使用帧动画。

使用方式

res/drawable目录下创建xml文件

方式一: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="@drawable/img0" android:duration="100"/>
	    <item android:drawable="@drawable/img1" android:duration="100"/>
	    <item android:drawable="@drawable/img2" android:duration="100"/>
	    <item android:drawable="@drawable/img3" android:duration="100"/>
	</animation-list>

将上述的Drawable作为View的背景并通过Drawable来播放动画即可:
启动
// 1. 设置动画
xxxview.setImageResource(R.drawable.xxxfilename);
// 2. 获取动画对象
animationDrawable = (AnimationDrawable) xxxview.getDrawable();
// 3. 启动动画
animationDrawable.start();

停止
// 1. 设置动画
xxxview.setImageResource(R.drawable.xxxfilename);
// 2. 获取动画对象
animationDrawable = (AnimationDrawable) xxxview.getDrawable();
// 3. 暂停动画
animationDrawable.stop();

方式二:java

// 方式2:
// 直接从drawable文件夹获取动画资源(图片)
animationDrawable = new AnimationDrawable();
for (int i = 0; i <= 25; i++) {
	//第一个参数:资源名称,第二个参数:资源类型,如drawable,第三个参数:包名
	int id = getResources().getIdentifier("a" + i, "drawable", getPackageName());
	Drawable drawable = getResources().getDrawable(id);
	animationDrawable.addFrame(drawable, 100);
}

启动
// 1. 获取资源对象
xxxview.setImageDrawable(animationDrawable);
// 2. 停止动画
// 特别注意:在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次
animationDrawable.stop();
// 3. 启动动画
animationDrawable.start();

停止
// 1. 获取资源对象
xxxview.setImageDrawable(animationDrawable);
// 2. 停止动画
animationDrawable.stop();

参考资料

https://carsonho.blog.csdn.net/article/details/79860980

Android开发艺术探索

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值