【android】Rotate3dAnimation实现3D旋转动画
2015-11-24 22:09
627 查看
最近接触了动画方面点点滴滴,看到一个关于3D旋转动画方面蛮有趣的小按理,整理出来和大家分享一下。
先来看下效果:
3D效果的实现主要用过Camera,调用camera的rotateX()、rotateY()、rotateZ()方法并传入相应的角度使View能够绕坐标轴旋转,这个按理主要让一个ListView和一个ImageView绕y轴旋转。
首先,通过一个自定义Rotate3dAnimation类扩展之Animation类,并重写它的applyTransformation()方法以及提供指定时间的变换矩阵,通过camera类得到一个依据旋转轴旋转的matrix矩阵并将这个矩阵传入到Transformation对象中去。实现代码如下:
在Activity的布局文件中奖ListView和ImageView放在同一个FrameLayout中,ListView和ImageView位置相互重叠,先后对两个View实现动画效果(ListVIew从0°旋转到90°或者ImageView实现从180°旋转到90°)需要注意一点的是:程序中通过mposition值的大小来判定在旋转后显示或者隐藏的是ListVIew还是ImageView。代码如下:
文章最后附上自定义Rotate3dAnimation完整代码如下:
先来看下效果:
3D效果的实现主要用过Camera,调用camera的rotateX()、rotateY()、rotateZ()方法并传入相应的角度使View能够绕坐标轴旋转,这个按理主要让一个ListView和一个ImageView绕y轴旋转。
首先,通过一个自定义Rotate3dAnimation类扩展之Animation类,并重写它的applyTransformation()方法以及提供指定时间的变换矩阵,通过camera类得到一个依据旋转轴旋转的matrix矩阵并将这个矩阵传入到Transformation对象中去。实现代码如下:
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }
在Activity的布局文件中奖ListView和ImageView放在同一个FrameLayout中,ListView和ImageView位置相互重叠,先后对两个View实现动画效果(ListVIew从0°旋转到90°或者ImageView实现从180°旋转到90°)需要注意一点的是:程序中通过mposition值的大小来判定在旋转后显示或者隐藏的是ListVIew还是ImageView。代码如下:
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) { } }
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; Rotate3dAnimation rotation; if (mPosition > -1) { mPhotosList.setVisibility(View.GONE); mImageView.setVisibility(View.VISIBLE); mImageView.requestFocus(); rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false); } else { mImageView.setVisibility(View.GONE); mPhotosList.setVisibility(View.VISIBLE); mPhotosList.requestFocus(); rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false); } rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new DecelerateInterpolator()); mContainer.startAnimation(rotation); } }另外,分别对listView和ImageView设置监听事件
public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // Pre-load the image then start the animation mImageView.setImageResource(PHOTOS_RESOURCES[position]); applyRotation(position, 0, 90); } public void onClick(View v) { applyRotation(-1, 180, 90); }
private void applyRotation(int position, float start, float end) { // Find the center of the container final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; // Create a new 3D rotation with the supplied parameter // The animation listener is used to trigger the next animation final Rotate3dAnimation rotation = new Rotate3dAnimation(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); }
文章最后附上自定义Rotate3dAnimation完整代码如下:
public class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
private final boolean mReverse;
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); camera.save(); if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }
}
相关文章推荐
- android开发步步为营之84:selector与shape的结合使用
- android112 c代码打印日志,c反编译调用java
- Android任务和返回栈完全解析,细数那些你所不知道的细节
- androidStudio的可视化界面为什么打不开?
- Android自定义ViewGroup之子控件的自动换行和添加删除
- 记录android反射机制【一】
- Android自定义组件之自动换行View - 儒雅小生
- android 帮助页
- android 利用countDownLatch实现主线程与子线程之间的同步
- android局域网通信( 一)
- Android SDK 国内镜像
- Android jni开发资料--NDK环境搭建
- Android使用XMPP协议、Openfire服务器和Smack类库实现即时通信
- android studio 安装报错 unable to run mksdcard sdk tool
- android 不同分辨率适配
- android选择相片和拍照保存
- Android文本目录介绍
- Android——调用系统摄像头拍照的问题
- Android SwipeRefreshLayout官方下拉刷新控件介绍(与知乎Android客户端下拉刷新一样!!)
- 打造私人在线视频播放器,就是这么简单................