反转效果是很常见的,以前使用的时候,每次都要重新写,现在写了一个工具类,方便使用。
这里主要是作用于两个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的布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yzk.rotatetow.MainActivity" > <ImageView android:id="@+id/front" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/front" android:visibility="visible" /> <ImageView android:id="@+id/back" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/back" android:visibility="gone" /> </RelativeLayout>
在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