animatons 种类
(屏幕宽度坐标为“100%p”
快速使用活动切换xml动画:overridePendingTransition())
两种明显的框架:
- 属性动画:最有力和灵活的动画系统从android3.0引入
试图动画:缓慢并且不灵活,从属性动画引入后被废弃
在这些动画框架下,五种相关的动画类型:属性动画:介于两个值之间的动画,常常用于屏幕上的view的动作例如:旋转图片,淡出一个按钮
- 活动转换:当一个活动进入屏幕时的动画
- 碎片转换:当一个碎片进入或者推出屏幕时的动画
- 布局动画:允许为布局容器或viewGroup添加动画,所有内部的改变都可以动画化
- 绘图动画:快速连续的显示drawable
Material动画原则
在android5.0放出了动画的相关准则主要有五点
- 实际运动:MD中的动作不应该只是漂亮,应该代表着实际空间的关系,作用性和目的性
- 响应交互:当用户与app交互时候,漂亮而且具有逻辑的动画将取悦用户
- 有意义的转换:精心编排的动作设计可以有效的引导用户,避免用户迷惑
- 可爱的细节:动画可以存在于各种细节当中,从良好设计的图标到关键的转换动作。所有元素构建一个无缝的漂亮的和功能性的体验
属性动画
在android3.0引入的属性。
常用的属性包括:
alpha –>Fade in or out淡入或者淡出
rotation, rotationX, rotationY –>Spin or flip旋转或者翻转
scaleX, scaleY –>Grow or shrink伸展收缩
x, y, z –>Position位置
translationX, translationY, translationZ (API 21+)
–>Offset from Position位置偏移
在过去我们为了兼容3.0系统的动画一般用NineOldAndroids库,虽然现在已经被废弃但是仍然能够使用在app/build.gradle
文件中
compile 'com.nineoldandroids:library:2.4.0'
简化常用动画的库代码家
使用ObjectAnimator
我们可以使用这个类执行简单的动画对于一个特定的对象 。
button1 = (Button) findViewById(R.id.bt_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//参数一:对象,参数二:动画效果,参数三值:最大为1.0
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(button1, "alpha", 0.9f);
fadeAnim.start();
float i = button1.getAlpha();
Log.d("float", String.valueOf(i));
}
});
一个旋转的例子:输入了两个值将在之间变换,可以使用getxxx和setxxx方法进行调整
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//参数一:对象,
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(button1, "rotation", 90f, -90f);
fadeAnim.start();
float i = button1.getRotation();
Log.d("float", String.valueOf(i));
}
});
也可以使用在4.0系统中的属性设置,即将第二个属性设置为ALPHA, ROTATION, ROTATION_X, ROTATION_Y, SCALE_X, SCALE_Y, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, X, Y, Z 好处是属性检查不像运行时反射那样慢
设置属性动画的持续时间或重复
我们可以设置额外的属性
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(button1, View.SCALE_X, 1.0f, 2.0f);
//动画的持续时间
fadeAnim.setDuration(5000);
//动画的持续次数,这里为无限
fadeAnim.setRepeatCount(ValueAnimator.INFINITE);
//当动画到达结束时候的模式,这里为重新开始
fadeAnim.setRepeatMode(ValueAnimator.RESTART);
fadeAnim.start();
设置插入
设置属性动画时我们不单要考虑变换动画的值还要考虑移动的轨迹,可以指定·TimeInterpolator
属性
ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(button1, View.Y, 500, 800);
//动画的持续时间
fadeAnim.setDuration(5000);
//动画形式,这里为在底部弹跳
fadeAnim.setInterpolator(new BounceInterpolator());
//当动画到达结束时候的模式,这里为重新开始
fadeAnim.setRepeatMode(ValueAnimator.RESTART);
fadeAnim.start();
其他轨迹:
AccelerateInterpolator –>Rate of change starts out slowly and and then accelerate加速进入
BounceInterpolator –>Change bounces right at the end底部弹跳
DecelerateInterpolator Rate of change starts out quickly and and then decelerates –>最后减速
LinearInterpolator Rate of change is constant throughout匀速进入
监听动画的生命周期
可以创建一个AnimatorListenerAdapter的类用来管理动画,onAnimationStart
onAniamtionEnd
ObjectAnimator anim = ObjectAnimator.ofFloat(v, "alpha", 0.2f);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(MainActivity.this, "End", Toast.LENGTH_SHORT).show();
}
});
anim.start();
组合动画
在AnimatorSet对象中设置多重动画,注意`ofObject()
方法
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(textView, View.SCALE_X, 1.0f, 2.0f).setDuration(2000),
ObjectAnimator.ofFloat(textView, View.SCALE_Y, 1.0f, 2.0f).setDuration(2000),
//参数三位类型求值器,当需要提供必要的插值时将会被调用,从Object类的值中获取动画的值。
ObjectAnimator.ofObject(textView, "backgroundColor", new ArgbEvaluator(), 0xFFFF8080,
0xFF8080FF)
);
set.start();
我们可以在
我们可以在一个AnimatorSet中嵌套其他的animatorSet对象,例如set1.playTogether(objectAnimator1, objectAnimator2);
set2.playTogether(objectAnimator3, objectAnimator4);
set3.playSequentially(set1, set2);
顺序播放,当前者完成,后者开始播放
set3.Start();
复杂的例子:
使用set1.play(1).with(2)
两个动画合并播放
set1.play(1).after(2)
先播放2再播放1
set1.play(1).before(2)
先播放1再播放2
play()内的对象是其他动画的依靠,所以其他对象都将其作为参照物,参照物只能有一个,例如 play(1).before(2).before(3)
1播放完成后2和3会一起播放,因为他们都将1作为照物
在java中使用ViewPropertyAnimator
不依靠库
如果只需要支持3.0和以上的版本的话,可以直接使用animate()
方法,这个方法具有许多的属性比如opacity,rotation,scale,x&y位置,等等,例如
textView.animate().alpha(0.5f).rotation(90f).scaleX(2).xBy(100).yBy(100).setDuration(1000)
.setStartDelay(10)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Toast.makeText(MainActivity.this, "Started..", Toast.LENGTH_SHORT).show();
}
});
使用XML设置动画
首先我们需要创建一个XML文件去形容对象的相关属性,例如
在res/animator/multi
文件中创建一个资源文件
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together"><!--同时播放-->
<objectAnimator android:propertyName="alpha"
android:valueTo="0.5"/>
<objectAnimator android:propertyName="rotation"
android:valueTo="90.0"/>
<objectAnimator android:propertyName="scaleX"
android:valueTo="2.0"/>
<objectAnimator android:propertyName="translationX"
android:valueTo="100.0"/>
<objectAnimator android:propertyName="translationY"
android:valueTo="100.0"/>
</set>
在主活动中利用AnimatorInflater类将XML文件转换为一个Animator对象,然后添加一个监听器。
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.multi);//AnimatorInflater.loadAnimator()将一个动画相关的XML文件转换成一个Animator对象
anim.setTarget(button);
anim.setDuration(2000);
anim.setStartDelay(100);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Toast.makeText(MainActivity.this, "started...", Toast.LENGTH_SHORT).show();
}
});
anim.start();
Layout Animations 布局动画
当一个布局弟一次出现在屏幕上面时,可以使用android:;layoutAnimation
属性指定执行的动画,将体现在所有布局内的控件上。
1. 首先我们定义当一个布局出现的时候的一个动画文件,res/anim/slide_right.xml
定义从屏幕右面划入我的结果是从左方划入
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="2000" />
</set>
- 然后创建一个引用上面动画的layoutAnimation的文件
layout_bottom_to_top_slide
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="30%"
android:animationOrder="normal"
android:animation="@anim/slide_right"/><!--按照相反的顺序执行-->
- 在布局文件上引用当前布局动画
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.codepath.animationstest.MainActivity"
android:layoutAnimation="@anim/layout_bottom_to_top_slide">
现在每个布局内的view将会全部使用这个动画。
Animations Changes
Layout Change Animations允许我们将任何ViewGroup或者LayoutContainer动画化,比如ListView,当动画启用时,任何其中的views的变化都将自动的动画化,尤其对于ListView来说。
为了启用自动的动画,我们需要设置ViewGroup的XML文件中的animateLayoutChanges
属性
<LinearLayout
...
android:animateLayoutChanges="true">
<ListView android:id="@+id/list"
android:animateLayoutChanges="true"
...
/>
</LinearLayout>
这样就会启用自动的动画效果
显示GIF
直接参考:http://guides.codepath.com/android/Animations#lollipop-animations
Lollipop Animations
在5.0几个新的动画效果出现包括:
共享元素动画转换:
涟漪动画
圆圈动画