关于动画,可使用代码(灵活),xml(固定)两种实现方式. 本篇在第一个平移动画中会使用两种方式演示,其余均使用代码实现. 以下为本篇目录.
类 | 动画 |
---|---|
Tween Animation |
补间动画 |
TranslateAnimation 对应
|
平移 |
ScaleAnimation 对应
|
放缩 |
AlphaAnimation 对应
|
透明 |
RotateAnimation 对应
|
旋转 |
FrameAnimation |
帧动画 |
overridePendingTransition |
Activity跳转动画 |
LayoutAnimation |
ListView条目加载动画 |
属性动画 |
Translate
xml,在res\anim目录下. 根标签即为traslate,其余类似
<translate
android:duration="2000" // 动画持续时长
android:fillAfter="true" // 是否保持动画结束状态
android:fromXDelta="0" // 动画起始坐标
android:fromYDelta="0"
android:repeatCount="1" // 动画重复次数
android:repeatMode="reverse" // 重复模式
android:toXDelta="1.5" // 动画终点坐标
android:toYDelta="0">
</translate>
代码
Animation.RELATIVE_TO_SELF
:指动画相对自身还是父容器.AnimationListener()
:添加动画监听.
onAnimationStart
:监听动画开始.onAnimationEnd
:监听动画结束.onAnimationRepeat
:监听动画重复过程.
Animation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 3.0f, Animation.RELATIVE_TO_SELF,
0f, Animation.RELATIVE_TO_SELF, 0f);
ta.setDuration(2000);
ta.setRepeatMode(Animation.REVERSE);
ta.setRepeatCount(1);
ta.setFillAfter(true);
ta.setAnimationListener(new Animation.AnimationListener() { // 动画监听:开始、重复中、结束
@Override public void onAnimationStart(Animation animation) { tv.setText("start..."); }
@Override public void onAnimationEnd(Animation animation) { tv.setText("end..."); }
@Override public void onAnimationRepeat(Animation animation) { tv.setText("repeat..."); }
});
iv.setImageResource(R.drawable.dzcj);
iv.startAnimation(ta);
scale
// float fromX: 动画起始时,X坐标上的伸缩尺寸.
// float toX: 动画结束时,X坐标上的伸缩尺寸.
// float fromY: 动画起始时,Y坐标上的伸缩尺寸.
// float toY: 动画结束时,Y坐标上的伸缩尺寸.
// int pivotXType: 动画在X轴相对于物件位置类型.
// float pivotXValue: 动画相对于物件的X坐标的开始位置.
// int pivotYType: 动画在Y轴相对于物件位置类型.
// float pivotYValue: 动画相对于物件的Y坐标的开始位置.
Animation sa = new ScaleAnimation(1f, 3.5f, 1f, 3.5f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000);
sa.setRepeatMode(Animation.REVERSE);
sa.setRepeatCount(1);
sa.setFillAfter(true);
iv.setImageResource(R.drawable.dzcj);
iv.startAnimation(sa);
alpha
// arg1:开始透明度.
// arg2:结束透明度.
Animation aa = new AlphaAnimation(0.0f, 1.0f);
aa.setDuration(2000);
aa.setRepeatMode(Animation.REVERSE);
aa.setRepeatCount(1);
aa.setFillAfter(true);
iv.setImageResource(R.drawable.dzcj);
iv.startAnimation(aa);
rotate
// arg1:起始角度.
// arg2:终止角度.
Animation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(2000);
ra.setRepeatMode(Animation.REVERSE);
ra.setRepeatCount(1);
ra.setFillAfter(true);
iv.setImageResource(R.drawable.dzcj);
iv.startAnimation(ra);
AnimaitionSet:补间动画集合
xml中的动画集合
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha
android:duration="2000"
android:fillAfter="true"
android:fromAlpha="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:toAlpha="1" />
<scale
android:duration="2000"
android:fillAfter="true"
android:fromXScale="0.5"
android:fromYScale="0.5"
android:repeatCount="1"
android:repeatMode="reverse"
android:toXScale="1.5"
android:toYScale="1.5" />
<translate
android:duration="2000"
android:fillAfter="true"
android:fromXDelta="0"
android:fromYDelta="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:toXDelta="1.5"
android:toYDelta="0" />
<rotate
android:duration="2000"
android:fillAfter="true"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="reverse"
set>
代码中添加动画集合
通过AnimationUtils.loadAnimation()
:添加动画集合,需要上下文.
Animation set = AnimationUtils.loadAnimation(getActivity(), R.anim.anim_set);
iv.setImageResource(R.drawable.dzcj);
iv.startAnimation(set);
类似于gif图片,就是几张图片按顺序播放.
先将准备好的图片作为 item 添加到xml文件中.
oneshot:是否轮播,true 只播放一遍. false 重复轮播.
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/dzcj"
android:duration="500" />
<item
android:drawable="@drawable/ddgl"
android:duration="500" />
<item
android:drawable="@drawable/gzj"
android:duration="500" />
animation-list>
代码
iv.setImageResource(R.drawable.drawable_frame);
AnimationDrawable ad = (AnimationDrawable) iv.getDrawable();
ad.start();
Activity 跳转动画,无非是前端 Activity 添加消失动画,后端 Activity 添加进入动画.
xml 中写好的进出动画集合(我们的动画很绚丽,小伙伴尝试一下).
zoom_out
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:zAdjustment="top">
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0"
android:toYScale="0" />
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0" />
<rotate
android:duration="500"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="180" />
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="50%"
android:toYDelta="50%" />
set>
zoom_in
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:startOffset="450">
<scale
android:duration="500"
android:fromXScale="0"
android:fromYScale="0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
<alpha
android:duration="500"
android:fromAlpha="0"
android:toAlpha="1.0" />
<rotate
android:duration="500"
android:fromDegrees="-180"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="0" />
<translate
android:duration="500"
android:fromXDelta="-50%"
android:fromYDelta="-50%"
android:toXDelta="0"
android:toYDelta="0" />
set>
代码
overridePendingTransition():必须写在 startActivity()
之后,否则我就不说.
startActivity(new Intent(getActivity(), SecondActivity.class));
getActivity().overridePendingTransition(R.anim.zoom_in, R.anim.zoom_out);
上面介绍的 Activity 跳转可以添加动画,同理,ListView 条目在加载时也可以添加条目动画,并且每个条目还可以单独添加个性化的动画.
xml 动画集合:复用上面写好的集合,就是集齐四个补间动画的布局.
代码
LayoutAnimationController()
:创建 LayoutAnimation 对象.
setOrder()
:设置动画加载方式(本例选择随机).
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.anim_set);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setOrder(LayoutAnimationController.ORDER_RANDOM);
lv.setLayoutAnimation(controller);
lv.setAdapter(adapter);
主要类:ValueAnimator、继承自ValueAnimator的ObjectAnimator、AnimatorSet
ObjectAnimator示例
1秒内绕View自身的X轴转720度也就
@OnClick(R.id.bt_anim)
void anim(View view) {
ObjectAnimator.ofFloat(view, "rotationX", 0.0f, 720.0f).setDuration(1000).start();
}
AnimatorSet示例
@OnClick(R.id.bt_anim)
void anim(View view) {
AnimatorSet as = new AnimatorSet();
as.playTogether(
ObjectAnimator.ofFloat(view, "rotationX", 0, 360),
ObjectAnimator.ofFloat(view, "rotationY", 0, 360),
ObjectAnimator.ofFloat(view, "rotation", 0, -135),
ObjectAnimator.ofFloat(view, "translationX", 0, 20),
ObjectAnimator.ofFloat(view, "translationY", 0, 20),
ObjectAnimator.ofFloat(view, "scaleX", 1, 1.2f),
ObjectAnimator.ofFloat(view, "scaleY", 1, 1.2f),
ObjectAnimator.ofFloat(view, "alpha", 1, 0.3f, 1)
);
as.setDuration(6000).start();
}
OOM:尽量避免使用帧动画
内存泄漏:避免动画无限循环,Activity退出时及时停止动画
兼容性
不要使用px,使用dp
View动画:即对View的影像做动画,当setVisibility(View.GONE)失效时使用view.clearAnimation()清除即可
动画元素的交互:3.0前View动画和属性动画均无法触发单击事件
硬件加速开启