反转效果是很常见的,以前使用的时候,每次都要重新写,现在写了一个工具类,方便使用。
这里主要是作用于两个View之间的反转,类似于硬币的反转。
思路:
1.使用旋转动画RotateAnimation,但是要使用带有深度的RotateAnimation动画
下载地址:http://download.csdn.net/detail/forwardyzk/8328895
2.如果是点击的正面View,顺时针旋转,那么就先把父窗体(包含正面View和背面View)旋转从0~90,动画结束后,正面View隐藏,背面view显示出来。
如果点击的是背面View,逆时针旋转,那么就把父窗体从旋转180~90,动画结束后,正面View显示出来,背面View隐藏。
3.为第一个动画添加动画监听,在动画结束后,执行另一半的动画。
设置点击View的第一个动画
/**
* @param position
* 0表示的是顺时针 1表示的是逆时针
* @param start
* 开始旋转的角度
* @param end
* 结束的角度
*/
private void applyRotation(int position, float start, float end) {
// 获取View的中心位置
final float centerX = mContainer.getWidth() / 2.0f;
final float centerY = mContainer.getHeight() / 2.0f;
// 创建一个带有深度3D旋转动画
final RotateAnimation rotation = new RotateAnimation(start, end,
centerX, centerY, 310.0f, true);
rotation.setDuration(500);
rotation.setFillAfter(true);
// 加速效果
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(position));// 当前动画的监听器,当前动画结束时,可以进行开启下一个动画
mContainer.startAnimation(rotation);
}
310.0表示旋转的深度,就是在Z轴方向的深度。
给这个动画添加了监听DisplayNextView,表示动画的监听器
private final class DisplayNextView implements Animation.AnimationListener {
private final int mPosition;
private DisplayNextView(int position) {
mPosition = position;
}
public void onAnimationStart(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
mContainer.post(new SwapViews(mPosition));
}
public void onAnimationRepeat(Animation animation) {
}
}
在onAnimationEnd中发送了一个通知,开启了一个线程,执行另一半动画。
/**
* 交换正反面的另一半的动画效果
*
*/
private final class SwapViews implements Runnable {
private final int mPosition;
public SwapViews(int position) {
mPosition = position;
}
public void run() {
final float centerX = mContainer.getWidth() / 2.0f;
final float centerY = mContainer.getHeight() / 2.0f;
RotateAnimation rotation;
if (mPosition == 0) {
// 点击的正面
mFrontView.setVisibility(View.GONE);
mBackView.setVisibility(View.VISIBLE);
rotation = new RotateAnimation(90, 180, centerX, centerY,
310.0f, false);
} else {
// 点击的背面
mBackView.setVisibility(View.GONE);
mFrontView.setVisibility(View.VISIBLE);
rotation = new RotateAnimation(90, 0, centerX, centerY, 310.0f,
false);
}
rotation.setDuration(500);
rotation.setFillAfter(true);
// 减速效果
rotation.setInterpolator(new DecelerateInterpolator());
mContainer.startAnimation(rotation);
}
}
如果是表示的是顺时针,那么后面一半的动画也应该是顺时针。旋转角度连起来就是0~90,90~180。
如果是表示的是逆时针,那么后面一半的动画也应该是逆时针。旋转角度连起来就是180~90,90~0。
下面把顺时针旋转和逆时针旋转封装各自的方法
/**
* 点击默认正面View的动画效果
*
* @param container
* 最外部的View,frontView和backView的父窗体
* @param frontView
* 默认的正面展示的View
* @param backView
* 默认背面展示的View
*/
public void clickFrontViewAnimation(View container, View frontView,
View backView) {
if (container == null || frontView == null || backView == null) {
return;
}
this.mContainer = container;
this.mFrontView = frontView;
this.mBackView = backView;
applyRotation(0, 0, 90);
}
/**
* 点击默认背面View的动画效果
*
* @param container
* 最外部的View,frontView和backView的父窗体
* @param frontView
* 默认的正面展示的View
* @param backView
* 默认背面展示的View
*/
public void clickBackViewAnimation(View container, View frontView,
View backView) {
if (container == null || frontView == null || backView == null) {
return;
}
this.mContainer = container;
this.mFrontView = frontView;
this.mBackView = backView;
applyRotation(1, 180, 90);
}
在activity_main.xml的布局
在MainActivity中写入代码
public class MainActivity extends Activity implements OnClickListener {
private RelativeLayout container;
private ImageView front;
private ImageView back;
private TowRotateAnimation animaton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView() {
container = (RelativeLayout) findViewById(R.id.container);
front = (ImageView) findViewById(R.id.front);
back = (ImageView) findViewById(R.id.back);
front.setOnClickListener(this);
back.setOnClickListener(this);
}
private void initData() {
animaton = new TowRotateAnimation();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.front:
animaton.clickFrontViewAnimation(container, front, back);
break;
case R.id.back:
animaton.clickBackViewAnimation(container, front, back);
break;
default:
break;
}
}
}
效果图:
源码下载:http://download.csdn.net/detail/forwardyzk/8329211