对于抽奖页 我们都用到了公告栏循环播放中奖名单的动画效果;一下介绍下自定义AutoTextView 实现了公告栏 文字 3D 翻转动画效果,无限循环播放,具有向上或者向下翻转特效。
现在先上效果图:
下面附上代码介绍:
自定义AutoTextView继承自TextSwitcher,实现文字切换,自定义动画,实现3d动画效果;
class Rotate3dAnimation extends Animation {
private final float mFromDegrees; //初始值
private final float mToDegrees; //最终值
private final boolean mTurnIn; //进
private final boolean mTurnUp; //出
private float mCenterX;
private float mCenterY;
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees, boolean turnIn, boolean turnUp) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mTurnIn = turnIn;
mTurnUp = turnUp;
}
//初始化动作
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mCenterY = getHeight() / 2;
mCenterX = getWidth() / 2;
}
//定义动画效果
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
//当前值 = 初始值 + (最终值 - 初始值) * interpolatedTime;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final int derection = mTurnUp ? 1 : -1;
//通过camera进行一些矩阵操作,最后对matrix进行变化
final Matrix matrix = t.getMatrix();
camera.save();
if (mTurnIn) {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime - 1.0f), 0.0f);
} else {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime), 0.0f);
}
camera.rotateX(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
重新定义了一个Animation,覆写了initialize和applyTransformation方法,利用矩阵实现3D翻页特效
下面附上整体代码:
public class AutoTextView extends TextSwitcher implements ViewFactory {
private float mHeight;
private Context mContext;
//mInUp,mOutUp分别构成向上翻页的进出动画
private Rotate3dAnimation mInUp;
private Rotate3dAnimation mOutUp;
//mInDown,mOutDown分别构成向下翻页的进出动画
private Rotate3dAnimation mInDown;
private Rotate3dAnimation mOutDown;
public AutoTextView(Context context) {
this(context, null);
}
public AutoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.auto3d);
mHeight = a.getDimension(R.styleable.auto3d_textSize, 36);
a.recycle();
mContext = context;
init();
}
private void init() {
setFactory(this);
//向上翻页的进出动画
mInUp = createAnim(-90, 0, true, true);//进动画
mOutUp = createAnim(0, 90, false, true);//出动画
//向下翻页的进出动画
mInDown = createAnim(90, 0, true, false);
mOutDown = createAnim(0, -90, false, false);
//继承TextSwitcher主要用于文件切换,比如 从文字A 切换到 文字 B,
//setInAnimation()后,A将执行inAnimation,
//setOutAnimation()后,B将执行OutAnimation
setInAnimation(mInUp);
setOutAnimation(mOutUp);
}
//动画
private Rotate3dAnimation createAnim(float start, float end, boolean turnIn, boolean turnUp) {
final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, turnIn, turnUp);
//设置动画持续时间
rotation.setDuration(300);
//fillAfter设为true,则动画执行后,控件将停留在动画结束的状态,false 则不停留
rotation.setFillAfter(false);
//设置动画的变化速度 加速
rotation.setInterpolator(new AccelerateInterpolator());
return rotation;
}
//这里返回的TextView,就是我们看到的View
@Override
public View makeView() {
TextView t = new TextView(mContext);
t.setGravity(Gravity.CENTER);
t.setTextSize(mHeight);
t.setSingleLine(true);
return t;
}
//定义动作,向下滚动翻页
public void previous() {
if (getInAnimation() != mInDown) {
setInAnimation(mInDown);
}
if (getOutAnimation() != mOutDown) {
setOutAnimation(mOutDown);
}
}
//定义动作,向上滚动翻页
public void next() {
if (getInAnimation() != mInUp) {
setInAnimation(mInUp);
}
if (getOutAnimation() != mOutUp) {
setOutAnimation(mOutUp);
}
}
/**
* 3d动画
* 重新定义了一个Animation,覆写了initialize和applyTransformation方法
*/
class Rotate3dAnimation extends Animation {
private final float mFromDegrees; //初始值
private final float mToDegrees; //最终值
private final boolean mTurnIn; //进
private final boolean mTurnUp; //出
private float mCenterX;
private float mCenterY;
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees, boolean turnIn, boolean turnUp) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mTurnIn = turnIn;
mTurnUp = turnUp;
}
//初始化动作
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mCenterY = getHeight() / 2;
mCenterX = getWidth() / 2;
}
//定义动画效果
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
//当前值 = 初始值 + (最终值 - 初始值) * interpolatedTime;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final int derection = mTurnUp ? 1 : -1;
//通过camera进行一些矩阵操作,最后对matrix进行变化
final Matrix matrix = t.getMatrix();
camera.save();
if (mTurnIn) {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime - 1.0f), 0.0f);
} else {
camera.translate(0.0f, derection * mCenterY * (interpolatedTime), 0.0f);
}
camera.rotateX(degrees);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
}
在activity中:
添加公告栏数据:
// 数据
mStringArray = new ArrayList();
mStringArray.add("137****1111 获得一等奖");
mStringArray.add("137****2222 获得二等奖");
mStringArray.add("137****3333 获得三等奖");
mStringArray.add("137****4444 获得四等奖");
通过headler发送消息开始自动翻转:
//开始动画
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEventHandler == null){
mEventHandler = new EventHandler(MainActivity.this);
//Value为FLAG的消息延迟0.5秒
mEventHandler.sendEmptyMessageDelayed(FLAG, 500);
}
}
});
public static class EventHandler extends Handler {
private WeakReference wr;
public EventHandler(MainActivity r) {
wr = new WeakReference(r);
}
@Override
public void handleMessage(android.os.Message msg) {
MainActivity activity = wr.get();
switch (msg.what) {
case 1:
if (activity.mStringArray.size()!= 0){
//无限循环
int i = activity.mLoopCount % activity.mStringArray.size();
// 向上滚动翻页
activity.mAutoTextView.next();
//给AutoTextView 设置文字
activity.mAutoTextView.setText(activity.mStringArray.get(i));
activity.mLoopCount ++;
//Value为FLAG的消息延迟0.5秒
activity.mEventHandler.sendEmptyMessageDelayed(FLAG, 500);
}
break;
}
}
}
在页面结束时一定要释放掉handler:
//停止动画,释放handler
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEventHandler != null){
//移出消息
mEventHandler.removeMessages(FLAG);
mEventHandler = null;
}
}
});
xml文件:
注意 一定要在布局文件的父控件添加:
xmlns:auto3d="http://schemas.android.com/apk/res-auto"
下面附上demo下载地址:
https://download.csdn.net/download/shanshan_1117/10315694
点击打开链接