Ken Burns特效只不过是视频产品中使用的一种平移和缩放静态图片的特效。效果如下:
要实现上述功能,需要使用Jake Wharton开发的Nine Old Androids库。这个库可以让开发者在旧版本上使用Android3.0的动画API。
要创建Ken Burns特效,需要预设一些动画。这些动画将随机应用到ImageView,当一个动画显示完毕,就开始显示另一个动画和图片。
Activity代码如下:
package com.example.huangfei.hack1;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.animation.AnimatorProxy;
import java.util.Random;
public class MainActivity extends Activity implements Animator.AnimatorListener {
private static final int ANIM_COUNT = 4;
private static final int[] PHOTOS = new int[]{R.drawable.photo1,
R.drawable.photo2, R.drawable.photo3, R.drawable.photo4,
R.drawable.photo5, R.drawable.photo6};
private FrameLayout mContainer;
private ImageView mImageView;
private Random mRandom = new Random();
private int mIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//创建布局容器
mContainer = new FrameLayout(this);
mContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
mImageView = createNewView();
mContainer.addView(mImageView);
setContentView(mContainer);
}
@Override
protected void onResume() {
super.onResume();
nextAnimation();
}
/** * 创建新的ImageView */
private ImageView createNewView() {
ImageView imageView = new ImageView(this);
imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
//设置要显示的图片并设置下一个要显示的图片的索引
imageView.setImageResource(PHOTOS[mIndex]);
mIndex = ++mIndex % PHOTOS.length;
return imageView;
}
/** * 该方法负责设置动画并启动动画 */
private void nextAnimation() {
AnimatorSet anim = new AnimatorSet();
//产生0-4的随机整数
int index = mRandom.nextInt(ANIM_COUNT);//随机选择动画
switch (index) {
case 0://缩放动画
anim.playTogether(ObjectAnimator.ofFloat(mImageView, "scaleX", 1.5f, 1f),
ObjectAnimator.ofFloat(mImageView, "scaleY", 1.5f, 1f));
break;
case 1:
anim.playTogether(ObjectAnimator.ofFloat(mImageView, "scaleX", 1f, 1.5f),
ObjectAnimator.ofFloat(mImageView, "scaleY", 1f, 1.5f));
break;
case 2://位移动画
/** * AnimatorProxy是定义在Nine Old Androids库中的类,用于修改View的属性。这个新的动画框架的 * 基础是:视图的属性随着时间的推移可以改变。之所以使用AnimatorProxy,是因为在Android3.0以 * 下版本,有些属性没有getters/setters方法。 */
AnimatorProxy.wrap(mImageView).setScaleX(1.5f);
AnimatorProxy.wrap(mImageView).setScaleY(1.5f);
anim.playTogether(ObjectAnimator.ofFloat(mImageView, "translationY", 80f, 0f));
break;
case 3:
default:
AnimatorProxy.wrap(mImageView).setScaleX(1.5f);
AnimatorProxy.wrap(mImageView).setScaleY(1.5f);
anim.playTogether(ObjectAnimator.ofFloat(mImageView, "translationX", 0f, 40f));
break;
}
//设置动画持续时间,设置动画监听器,启动动画
anim.setDuration(3000);
anim.addListener(this);
anim.start();
}
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
//动画结束时,从布局中移除之前的View,并添加新的View,而后开始显示下一个动画
mContainer.removeView(mImageView);
mImageView = createNewView();
mContainer.addView(mImageView);
nextAnimation();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
}
在上面的示例中,当切换视图时,我们也可以添加透明渐变动画(alpha animation)并且添加一个AnimationSet同时显示平移和缩放动画。可以从Nine Old Androids库的示例代码中获得更多启发。
新的动画API通常可以比旧的API实现更多潜在的功能。以下是新的API一些改进的简短列表:
1、旧版本的API只支持视图对象的动画效果。
2、旧版本的API仅限于移动、旋转、缩放、渐变等效果。
3、旧版本的API只改变视图移动时的视觉效果,并未改变其真实位置属性。
代码地址