Android 动画主要分来两类:
1.tweeted 动画 , 补间动画
2.frame 动画,
逐帧动画
首先来说说简单的
frame by frame 动画, 这个动画实现起来很简单,
但是在Android上用的不是很多, 我遇到的是在一些复杂的loading 动画时候用到
frame 动画 同样可以定义在Xml中, 同样也可以在代码中写
下面是在xml顶一个一个动画
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<!-- android:oneshot
如果为false 表示重复播放
如果为true 表示只播放一遍
-->
<item
android:drawable="@drawable/loading_1"
android:duration="60"/>
<!-- 每一个item 表示一帧-->
<item
android:drawable="@drawable/loading_2"
android:duration="60"/>
<item
android:drawable="@drawable/loading_3"
android:duration="60"/>
<item
android:drawable="@drawable/loading_4"
android:duration="60"/>
<item
android:drawable="@drawable/loading_5"
android:duration="60"/>
<item
android:drawable="@drawable/loading_6"
android:duration="60"/>
<item
android:drawable="@drawable/loading_7"
android:duration="60"/>
<item
android:drawable="@drawable/loading_8"
android:duration="60"/>
</animation-list>
当如果吧这个动画放在一个View上作为载体的画, 那上面的动画文件就需要放在 drawable文件夹下面了.
mImageView = (ImageView) findViewById(R.id.img);
mImageView.setBackgroundResource(R.drawable.loading);
mLoadingAnim = (AnimationDrawable) mImageView.getBackground();
如上代码所示, 通过ImageView 去加载动画, 获取到 mLoadingAnim 后可以控制动画了,
需要注意的是, 为了确保 动画里的每一帧不被自适应放大, 那么就 最好吧每一帧的图片放到 drawable-xxhpi文件夹中去,
这一问题是在为ProgressBar设置动画时 遇到的,
Progress设置动画如下:
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="28dp"
android:layout_height="28dp"
android:indeterminate="true"
android:indeterminateDrawable="@anim/loading"
/>
这里之前把动画的图片放到 drawable文件下发现怎么设宽高都会有问题, 现在把它放到
drawable-xxhpi 就好了 ,可以设置款到为28dp, 即这张图片的真是宽高,
但是还有一个问题就是, 我设置成 宽高wrap_content 还是会有问题, 这个问题下次整理ProgressBar的时候在做处理.
下面在来看看 用代码来实现
mLoadingAnim = new AnimationDrawable();
for (int i = 1; i <= 8; i++) {
int id = getResources().getIdentifier("loading_" + i, "drawable", getPackageName());
Drawable drawable = getResources().getDrawable(id);
mLoadingAnim.addFrame(drawable, 60);
}
mLoadingAnim.setOneShot(false);
mImageView.setBackgroundDrawable(mLoadingAnim);
ok 上面大致了解一下 逐帧动画的基本用法了
下面在来看看 tweeted
动画
动画的属性有:
alpha
渐变透明度动画效果
scale
渐变尺寸伸缩动画效果
translate
画面转换位置移动动画效果
rotate 画面转移旋转动画效果
下面看看在xml 定义这些动画,
Alpha
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="3000"
/>
<!-- 透明度控制动画效果 alpha
浮点型值:
fromAlpha 属性为动画起始时透明度
toAlpha 属性为动画结束时透明度
说明:
0.0表示完全透明
1.0表示完全不透明
以上值取0.0-1.0之间的float数据类型的数字
长整型值:
duration 属性为动画持续时间
说明:
时间以毫秒为单位
-->
</set>
Scale
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator=
"@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0.0"
android:toXScale="1.4"
android:fromYScale="0.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="700" />
</set>
<!-- 尺寸伸缩动画效果 scale
属性:interpolator 指定一个动画的插入器
在我试验过程中,使用android.res.anim中的资源时候发现
有三种动画插入器:
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
其他的属于特定的动画效果
浮点型值:
fromXScale 属性为动画起始时 X坐标上的伸缩尺寸
toXScale 属性为动画结束时 X坐标上的伸缩尺寸
fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
toYScale 属性为动画结束时Y坐标上的伸缩尺寸
说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明:
以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用
-->
Translate
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="30"
android:toXDelta="-80"
android:fromYDelta="30"
android:toYDelta="300"
android:duration="2000"
/>
<!-- translate 位置转移动画效果
整型值:
fromXDelta 属性为动画起始时 X坐标上的位置
toXDelta 属性为动画结束时 X坐标上的位置
fromYDelta 属性为动画起始时 Y坐标上的位置
toYDelta 属性为动画结束时 Y坐标上的位置
注意:
没有指定fromXType toXType fromYType toYType 时候,
默认是以自己为相对参照物
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
-->
</set>
Rotate
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="+350"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000" />
<!-- rotate 旋转动画效果
属性:interpolator 指定一个动画的插入器
在我试验过程中,使用android.res.anim中的资源时候发现
有三种动画插入器:
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
其他的属于特定的动画效果
浮点数型值:
fromDegrees 属性为动画起始时物件的角度
toDegrees 属性为动画结束时物件旋转的角度 可以大于360度
说明:
当角度为负数——表示逆时针旋转
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明: 以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
-->
</set>
接下来看如何使用这些动画
alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha);
mImageView.startAnimation(alphaAnimation);
先加载处动画, 然后在适当的时候调用view 的startAnimation 就可以执行动画了.
这样的动画有一个问题就是, 当动画结束后,不会改变View本身的任何属性,
比如说, 我们设定动画结束的alpha 是0.1 那么当动画结束之后view 有变成了原来的熟悉了
所以为了能让动画,在结束后保留相关的属性, 就引入了属性动画:
用例如下:
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "Alpha", mImageView.getAlpha(), 0.1f);
mObjectAnimator.setDuration(3000);
mObjectAnimator.start();
上面是一个改编透明度的动画
还有一些其他属性的相关动画 如下:
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "translationX", mImageView.getTranslationX(), 200);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "translationY", mImageView.getTranslationY(), 200);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "scaleX", mImageView.getScaleX(), 0.1f);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "scaleY", mImageView.getScaleY(), 0.1f);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "rotationX", mImageView.getRotationX(), 300);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "rotationY", mImageView.getRotationY(), 300);
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "rotation", mImageView.getRotation(), 300);
同时我还可以手动的设置这些View 这些属性:
mImageView.setAlpha(1.0f);
mImageView.setTranslationX(0);
mImageView.setTranslationY(0);
mImageView.setScaleX(1);
mImageView.setScaleY(1);
mImageView.setRotation(1);
mImageView.setRotationX(0);
mImageView.setRotationY(0);
在使用 scale 和rotation 动画时需要注意设置
缩放 与旋转的相对点
mImageView.setPivotX(0);
mImageView.setPivotX(0);
默认是View 的中心点, 里面的设置的值 是相对View 的左上角定点开始的
其实一些复杂的动画 就是多种动画组合在一起完成的,
下面就是多个动画一起执行的例子
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(duration);
animatorSet.playTogether(topLineAnim, bottomLineAnim);
animatorSet.setInterpolator(new OvershootInterpolator(1.5f));
animatorSet.start();
只要 在animatorSet de playTogether 方法中加入一起执行的 ObjectAnimator就可以了
对了说道动画, 就还要讲一讲插值器, 上面的setInterpolator 方法就是色值插值器
关于插值器的可以查看一下几篇文章
介绍 几种基本的插值器
介绍生成插值器的方法
动画的过程是可以监听的:
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
mIsStartingDateTransAnimation = false;
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
可以更具自己的需要重载一些方法,
这里需要注意的是,
在调用 AnimSet.cancel() 取消动画的时候
AnimatorListener 会回调 onAnimationEnd 和 onAnimationCancel
动画正常结束 只会调用 onAnimationEnd 方法.
mObjectAnimator = ObjectAnimator.ofFloat(mImageView, "scaleX", mImageView.getScaleX(), 0.1f)
除了以上这种构建属性动画的方式 还下面一种
PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat(View.ALPHA, 0, 1);
PropertyValuesHolder pvhTransY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, tipsTxt.getMeasuredHeight() * 2 / 3, 0);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(tipsTxt, pvhAlpha, pvhTransY);
animator.setDuration(450);
animator.start();
部分内容参考
http://blog.youkuaiyun.com/ithomer/article/details/7523328
9689

被折叠的 条评论
为什么被折叠?



