第二章 创建炫酷的动画效果

1. 使用TextSwitcher和ImageSwitcher

当我们需要改变界面上某一处文字时,通常使用TextView.setText()方法来实现,瞬间即完成。而TextSwitcher可以让我们在改变文字时添加一个退出和一个进入动画。TextSwitcher实现步骤如下:
1. 通过findViewById()初始化TextSwitcher控件
2. 通过switcher.setFactory()创建一个构造器,在这里添加textview
3. 添加文字进入动画 switcher.setInAnimation();
3. 添加文字退出动画 switcher.setOutAnimation();

具体实现代码如下:

public class MainActivity extends AppCompatActivity {

    private TextSwitcher mTextSwitcher;
    private String[] StringArray={"First","Second","Third"};
    private Button button;//点击按钮显示下一个词
    private int currentPosition=0;//记录当前显示的词
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化按钮
        button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onSwitchText();
            }
        });
        //初始化TextSwitcher
        mTextSwitcher=(TextSwitcher)findViewById(R.id.text_switcher);
        mTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
            @Override
            public View makeView() {
                TextView t = new TextView(MainActivity.this);
                t.setGravity(Gravity.CENTER);
                t.setTextSize(24);
                return t;
            }
        });
        mTextSwitcher.setInAnimation(this,android.R.anim.slide_in_left);
        mTextSwitcher.setOutAnimation(this,android.R.anim.slide_out_right);
        onSwitchText();
    }

    public void onSwitchText() {
        mTextSwitcher.setText(StringArray[currentPosition]);
        currentPosition++;
        if(currentPosition==StringArray.length){
            currentPosition=0;
        }
    }

}

ImageSwitcher和TextSwitcher实现方法类似,可以实现类似于图片滚动显示的效果。


2. 为ViewGroup的子View添加漂亮效果

默认情况下,View被加载到ViewGroup中的过程是瞬间完成的。然而我们也可以使用LayoutAnimationController为这个加载过程添加动画效果。

实现代码如下:

public class MainActivity extends ListActivity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getListView().setLayoutAnimation(
        new LayoutAnimationController(AnimationUtils.loadAnimation(
            this, R.anim.list_animation), 0.5f));

    setListAdapter(new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, Countries.COUNTRIES));
  }
}

R.anim.list_animation文件

<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <alpha
        android:duration="50"
        android:fromAlpha="0"
        android:toAlpha="1" />

    <translate
        android:duration="100"
        android:fromYDelta="-100%"
        android:toYDelta="0%" />

</set>

这里动画效果写在xml文件中,也可以通过java代码实现:

mListView = (ListView) findViewById(R.id.my_listview_id);
AnimationSet set = new AnimationSet(true); //动画集,可以添加多个动画
Animation animation = new AlphaAnimation(0.0f, 1.0f);//透明动画
animation.setDuration(50);
set.addAnimation(animation);
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);//平移动画
animation.setDuration(100); animation.
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);//第二个参数指定两个动画之间的间隔时间
mListView.setLayoutAnimation(controller);

平移动画的参数介绍:

public TranslateAnimation(int fromXType, float fromXValue, int toXType,float toXValue, int fromYType, float fromYValue, int toYType,float toYValue) {}

其中Type有三种:

Animation.ABSOLUTE   绝对位置
Animation.RELATIVE_TO_SELF  相对自身位置
Animation.RELATIVE_TO_PARENT  相对父控件位置


3.使用Canvas绘制动画

用Android官方api绘制动画时,可能会有某些局限。使用Canvas类提供的功能,我们能够直接在屏幕上绘制图形或动画。
下面的例子将 绘制一个正方形小方块,让它在屏幕上自行移动,当它移动到屏幕边缘时,将调转方向继续移动。
1. 首先创建一个Rectangle类,用它来绘制小方块,并提供移动,移动速度等控制方法。
public class Rectangle extends View {
  public static final int MAX_SIZE = 40;
  private static final int ALPHA = 255;
  private int mCoordX = 0;
  private int mCoordY = 0;
  private int mRealSize = 40;
  private int mSpeedX = 3;
  private int mSpeedY = 3;
  private boolean goRight = true;
  private boolean goDown = true;
  private DrawView mDrawView;
  private Paint mInnerPaint;
  private RectF mDrawRect;

  public Rectangle(Context context, DrawView drawView) {
    super(context);
    mDrawView = drawView;
    mInnerPaint = new Paint();
    mDrawRect = new RectF();
    /* Red is default */
    mInnerPaint.setARGB(ALPHA, 255, 0, 0);
    mInnerPaint.setAntiAlias(true);
  }

  public void setARGB(int a, int r, int g, int b) {
    mInnerPaint.setARGB(a, r, g, b);
  }

  public void move() {
    moveTo(mSpeedX, mSpeedY);
  }

  private void moveTo(int goX, int goY) {
    // check the borders, and set the direction if a border has reached
    if (mCoordX > (mDrawView.width - MAX_SIZE)) {
      goRight = false;
    }
    if (mCoordX < 0) {
      goRight = true;
    }
    if (mCoordY > (mDrawView.height - MAX_SIZE)) {
      goDown = false;
    }
    if (mCoordY < 0) {
      goDown = true;
    }
    // move the x and y
    if (goRight) {
      mCoordX += goX;
    } else {
      mCoordX -= goX;
    }
    if (goDown) {
      mCoordY += goY;
    } else {
      mCoordY -= goY;
    }

  }

  public int getSpeedX() {
    return mSpeedX;
  }
  public void setSpeedX(int speedX) {
    mSpeedX = speedX;
  }
  public int getmSpeedY() {
    return mSpeedY;
  }
  public void setSpeedY(int speedY) {
    mSpeedY = speedY;
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(getResources().getColor(android.R.color.white));
    mDrawRect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY
        + mRealSize);
    canvas.drawRoundRect(mDrawRect, 0, 0, mInnerPaint);
  }
}
2.创建DrawView类,作为小方块的载体
public class DrawView extends View {
  private Rectangle mRectangle;
  public int width;
  public int height;

  public DrawView(Context context) {
    super(context);
    mRectangle = new Rectangle(context, this);//初始化小方块
    mRectangle.setARGB(255, 255, 0, 0); //设置小方块颜色
    mRectangle.setSpeedX(3); //小方块X轴移动速度
    mRectangle.setSpeedY(3);//小方块Y轴移动速度
  }

  @Override
  protected void onDraw(Canvas canvas) {
    mRectangle.move(); //让小方块移动
    mRectangle.onDraw(canvas);//绘制小方块
    invalidate(); //强制绘制,这意味着onDraw方法绘制完成之后会接着重新绘制
  }

}

3.在Activity中加载出来

public class MainActivity extends Activity {

  private DrawView mDrawView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Display display = getWindowManager().getDefaultDisplay();//获取屏幕
    mDrawView = new DrawView(this);
    mDrawView.height = display.getHeight();//让drawView填充整个屏幕
    mDrawView.width = display.getWidth();

    setContentView(mDrawView);//加载drawView
  }
}

在onDraw()方法中通过调用invalidate()更新view的位置是实现自定义动画的一种简易方式,如果想做一个小游戏,这个小技巧也许适用。


4.实现Ken Burns effect幻灯片效果

Ken Burns effect是一种让静态图片平移和放大的视频特效。下面这个例子实现让图片平移和放大:
首先创建一个layout容器,往里面添加一个ImageView
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mImageContainer=new FrameLayout(this);
        mImageContainer.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
        imageView=createNewImageView();
        mImageContainer.addView(imageView);
        setContentView(mImageContainer);
    }
    private ImageView createNewImageView(){
        ImageView img=new ImageView(this);
        img.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        img.setImageResource(images[imageIndex]);
        img.setScaleType(ImageView.ScaleType.FIT_XY);
        imageIndex=imageIndex+1<images.length?imageIndex+1:0;
        return img;
    }
然后为ImageView添加动画
private void nextAnimation(){
        AnimatorSet animatorSet=new AnimatorSet();
        int index=random.nextInt(images.length);
        switch (index){
            case 0://放大
                animatorSet.playTogether(
                        ObjectAnimator.ofFloat(imageView,"scaleX",1f,1.5f),
                        ObjectAnimator.ofFloat(imageView,"scaleY",1f,1.5f)
                );
                break;
            case 1://平移
                AnimatorProxy.wrap(imageView).setScaleX(1.5f);
                AnimatorProxy.wrap(imageView).setScaleY(1.5f);
                animatorSet.playTogether(ObjectAnimator.ofFloat(imageView,
                        "translationX", 0f, 80f));
                break;
        }
        animatorSet.setDuration(5000);
        animatorSet.addListener(this);
        animatorSet.start();

    }

其实这个动画效果就是使用了NineOldAndroid开源库,属性动画,与旧版本的动画相比,属性动画解决了老版本动画的如下缺点:
1.老版本动画只支持View的动画效果
2.老版本动画只支持移动,缩放,旋转,透明度
3.老版本动画在view移动时只是视觉上移动,实际位置无法改变
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值