欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现文字翻转动画的效果

程序员文章站 2024-03-04 22:45:24
本文实现了android程序文字翻转动画的小程序,具体代码如下: 先上效果图如下: 要求: 沿y轴正方向看,数值减1时动画逆时针旋转,数值加1时动画顺...

本文实现了android程序文字翻转动画的小程序,具体代码如下:

先上效果图如下:

Android实现文字翻转动画的效果

要求:

沿y轴正方向看,数值减1时动画逆时针旋转,数值加1时动画顺时针旋转。

实现动画的具体细节见"rotateanimation.java"。为方便查看动画旋转方向,可以将rotateanimation.debug值设置为true即可。


rotateanimation参考自apidemos的rotate3danimation


rotateanimation的构造函数需有三个参数,分别说明动画组件的中心点位置及旋转方向。


rotateanimation.initialize()将初始化动画组件及其父容器的宽高;通常亦可进行另外的初始化工作,本例中用于执行对camera进行实例化赋值。


rotateanimation.applytransformation()第一个参数为动画的进度时间值,取值范围为[0.0f,1.0f],第二个参数transformation记录着动画某一帧中变形的原始数据。该方法在动画的每一帧显示过程中都会被调用。


在翻转过程中,为了避免在动画下半部分时图像为镜面效果影响数字的阅读,应将翻转角度做180度的减法。代码为

rotateanimation.applytransformation()中的:
if (overhalf) { 
  // 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。 
  degree = degree - 180; 
} 

动画翻转到一半后,应更新数字内容。为了得知翻转进度,于rotateanimation中设计一内部静态接口类"interpolatedtimelistener",该接口只有一个方法"interpolatedtime(float interpolatedtime)"可以将动画进度传递给监听发起者。

java代码如下,xml请根据效果图自行实现:


actrotate.java

package lab.sodino.rotate; 
 
import lab.sodino.rotate.rotateanimation.interpolatedtimelistener; 
import android.app.activity; 
import android.os.bundle; 
import android.util.log; 
import android.view.view; 
import android.view.view.onclicklistener; 
import android.widget.button; 
import android.widget.textview; 
 
/** 
 * @author sodino e-mail:sodinoopen@hotmail.com 
 * @version time:2012-6-27 上午07:32:00 
 */ 
public class actrotate extends activity implements onclicklistener, interpolatedtimelistener { 
  private button btnincrease, btndecrease; 
  private textview txtnumber; 
  private int number; 
  /** textnumber是否允许显示最新的数字。 */ 
  private boolean enablerefresh; 
 
  public void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.main); 
 
    btnincrease = (button) findviewbyid(r.id.btnincrease); 
    btndecrease = (button) findviewbyid(r.id.btndecrease); 
    txtnumber = (textview) findviewbyid(r.id.txtnumber); 
 
    btnincrease.setonclicklistener(this); 
    btndecrease.setonclicklistener(this); 
 
    number = 3; 
    txtnumber = (textview) findviewbyid(r.id.txtnumber); 
    txtnumber.settext(integer.tostring(number)); 
  } 
 
  public void onclick(view v) { 
    enablerefresh = true; 
    rotateanimation rotateanim = null; 
    float cx = txtnumber.getwidth() / 2.0f; 
    float cy = txtnumber.getheight() / 2.0f; 
    if (v == btndecrease) { 
      number--; 
      rotateanim = new rotateanimation(cx, cy, rotateanimation.rotate_decrease); 
    } else if (v == btnincrease) { 
      number++; 
      rotateanim = new rotateanimation(cx, cy, rotateanimation.rotate_increase); 
    } 
    if (rotateanim != null) { 
      rotateanim.setinterpolatedtimelistener(this); 
      rotateanim.setfillafter(true); 
      txtnumber.startanimation(rotateanim); 
    } 
  } 
 
  @override 
  public void interpolatedtime(float interpolatedtime) { 
    // 监听到翻转进度过半时,更新txtnumber显示内容。 
    if (enablerefresh && interpolatedtime > 0.5f) { 
      txtnumber.settext(integer.tostring(number)); 
      log.d("android_lab", "setnumber:" + number); 
      enablerefresh = false; 
    } 
  } 
} 

rotateanimation.java

import android.view.animation.animation; 
import android.view.animation.transformation; 
 
/** 
 * @author sodino e-mail:sodinoopen@hotmail.com 
 * @version time:2012-6-27 上午07:32:00 
 */ 
public class rotateanimation extends animation { 
  /** 值为true时可明确查看动画的旋转方向。 */ 
  public static final boolean debug = false; 
  /** 沿y轴正方向看,数值减1时动画逆时针旋转。 */ 
  public static final boolean rotate_decrease = true; 
  /** 沿y轴正方向看,数值减1时动画顺时针旋转。 */ 
  public static final boolean rotate_increase = false; 
  /** z轴上最大深度。 */ 
  public static final float depth_z = 310.0f; 
  /** 动画显示时长。 */ 
  public static final long duration = 800l; 
  /** 图片翻转类型。 */ 
  private final boolean type; 
  private final float centerx; 
  private final float centery; 
  private camera camera; 
  /** 用于监听动画进度。当值过半时需更新txtnumber的内容。 */ 
  private interpolatedtimelistener listener; 
 
  public rotateanimation(float cx, float cy, boolean type) { 
    centerx = cx; 
    centery = cy; 
    this.type = type; 
    setduration(duration); 
  } 
 
  public void initialize(int width, int height, int parentwidth, int parentheight) { 
    // 在构造函数之后、gettransformation()之前调用本方法。 
    super.initialize(width, height, parentwidth, parentheight); 
    camera = new camera(); 
  } 
 
  public void setinterpolatedtimelistener(interpolatedtimelistener listener) { 
    this.listener = listener; 
  } 
 
  protected void applytransformation(float interpolatedtime, transformation transformation) { 
    // interpolatedtime:动画进度值,范围为[0.0f,10.f] 
    if (listener != null) { 
      listener.interpolatedtime(interpolatedtime); 
    } 
    float from = 0.0f, to = 0.0f; 
    if (type == rotate_decrease) { 
      from = 0.0f; 
      to = 180.0f; 
    } else if (type == rotate_increase) { 
      from = 360.0f; 
      to = 180.0f; 
    } 
    float degree = from + (to - from) * interpolatedtime; 
    boolean overhalf = (interpolatedtime > 0.5f); 
    if (overhalf) { 
      // 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。 
      degree = degree - 180; 
    } 
    // float depth = 0.0f; 
    float depth = (0.5f - math.abs(interpolatedtime - 0.5f)) * depth_z; 
    final matrix matrix = transformation.getmatrix(); 
    camera.save(); 
    camera.translate(0.0f, 0.0f, depth); 
    camera.rotatey(degree); 
    camera.getmatrix(matrix); 
    camera.restore(); 
    if (debug) { 
      if (overhalf) { 
        matrix.pretranslate(-centerx * 2, -centery); 
        matrix.posttranslate(centerx * 2, centery); 
      } 
    } else { 
      //确保图片的翻转过程一直处于组件的中心点位置 
      matrix.pretranslate(-centerx, -centery); 
      matrix.posttranslate(centerx, centery); 
    } 
  } 
 
  /** 动画进度监听器。 */ 
  public static interface interpolatedtimelistener { 
    public void interpolatedtime(float interpolatedtime); 
  } 
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!