Android
动画主要分为分为两大类(三种):
View
动画:补间动画、帧动画View动画通过对场景里的对象不断做图像变换(平移、缩放、旋转、透明度)从而产生动画效果,它是一种渐近式动画,并且支持自定义。
我们设置一个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
,即加速减速插值器。
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 移动的结束值
/>
标签标示平移动画,对应TranslateAnimation
类,它可以使一个View
在水平和竖直方向完成平移的动画效果,它的一系列属性的含义如下:
缩放动画中有轴点的概念,举个例子,默认情况下轴点是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
。
标签表示缩放动画,对应ScaleAnimation
,它可以使View
具有放大或者缩小的动画效果,它的一系列属性的含义如下:
<?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坐标
/>
标签表示旋转动画,对于RotateAnimation,它可以使View具有旋转的动画效果,它的属性的含义如下:
<?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)
/>
标签表示透明度动画,对应AlphaAnimation
,它可以改变View的透明度,它的属性的含义如下:
<?xml version="1.0" encoding="utf-8"?>
// 采用< Set/>标签
<set xmlns:android="http://schemas.android.com/apk/res/android">
// 组合动画独特的属性
android:shareinterpolator = “true”
// 表示组合动画中的动画是否和集合共享同一个差值器
// 如果集合不指定插值器,那么子动画需要单独设置
// 组合动画播放时是全部动画同时开始
// 如果想不同动画不同时间开始就要使用android:startOffset属性来延迟单个动画播放时间
/>
标签表示动画集合,对应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) {
//动画重复执行的时候回调
}
});
Activity的动画切换效果存在两种方式:使用系统预设和自定义切换动画效果。
系统已经封装好的动画效果
淡入淡出:android.R.anim.fade_in、android.R.anim.fade_out
由左向右滑入:android.R.anim.slide_in_left、android.R.anim.slide_out_right
核心方法: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切换也有使用系统预设和自定义切换动画效果两种方式。
系统预设动画效果需要通过FragmentTransaction.setTransition(int transit)
进行设置
transit参数有三种
FragmentTransaction.TRANSIT_NONE
:无动画FragmentTransaction.TRANSIT_FRAGMENT_OPEN
:标准的打开动画效果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);
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、reverse
和random
,其中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);
可以看这一篇博客
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开发艺术探索