博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 3D旋转动画效果
阅读量:6282 次
发布时间:2019-06-22

本文共 9247 字,大约阅读时间需要 30 分钟。

hot3.png

主要介绍一下如何实现View的3D旋转效果,实现的主要原理就是围绕Y轴旋转,同时在Z轴方面上有一个深入的缩放。

演示的demo主要有以下几个重点:

1,自定义旋转动画

2,动画做完后,重置ImageView

1,自定义动画类

这里实现了一个Rotate3dAnimation的类,它扩展了Animation类,重写applyTransformation()方法,提供指定时间的矩阵变换,我们在这个方法里,就可以利用Camera类得得到一个围绕Y轴旋转的matrix,把这个matrix设置到Transformation对象中。
@Overrideprotected 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);}

2,如何使用这个动画类

在Activity中,我们有两个大小一样的ImageView,它们都放在FrameLayout中,这样他们位置是重叠的,对最上面的ImageView做动画(旋转角度从0到90),当动画做完后,再对后面的ImageView做动画(旋转角度从90到180),在这里,要控制相应的ImageView隐藏或显示。

private final class DisplayNextView implements Animation.AnimationListener {        public void onAnimationStart(Animation animation) {        }        public void onAnimationEnd(Animation animation) {            mContainer.post(new SwapViews());        }        public void onAnimationRepeat(Animation animation) {        }    }

动画做完后,执行的代码如下:

private final class SwapViews implements Runnable    {        @Override        public void run()        {            mImageView1.setVisibility(View.GONE);            mImageView2.setVisibility(View.GONE);            mIndex++;            if (0 == mIndex % 2)            {                mStartAnimView = mImageView1;            }            else            {                mStartAnimView = mImageView2;            }            mStartAnimView.setVisibility(View.VISIBLE);            mStartAnimView.requestFocus();            Rotate3dAnimation rotation = new Rotate3dAnimation(                    -90,                    0,                    mCenterX,                    mCenterY, mDepthZ, false);            rotation.setDuration(mDuration);            rotation.setFillAfter(true);            rotation.setInterpolator(new DecelerateInterpolator());            mStartAnimView.startAnimation(rotation);        }    }

3,完整代码如下

Rotate3dAnimActivity.java

public class Rotate3dAnimActivity extends Activity{    ImageView mImageView1 = null;    ImageView mImageView2 = null;    ImageView mStartAnimView = null;    View mContainer = null;    int mDuration = 500;    float mCenterX = 0.0f;    float mCenterY = 0.0f;    float mDepthZ  = 0.0f;    int mIndex = 0;        @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);                setContentView(R.layout.rotate_anim);                mImageView1 = (ImageView) findViewById(R.id.imageView1);        mImageView2 = (ImageView) findViewById(R.id.imageView2);        mContainer  = findViewById(R.id.container);        mStartAnimView = mImageView1;                findViewById(R.id.button1).setOnClickListener(new View.OnClickListener()        {            @Override            public void onClick(View v)            {                mCenterX = mContainer.getWidth() / 2;                mCenterY = mContainer.getHeight() / 2;                                getDepthZ();                                applyRotation(mStartAnimView, 0, 90);            }        });                InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);        imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);    }        private void getDepthZ()    {        EditText editText = (EditText) findViewById(R.id.edit_depthz);        String string = editText.getText().toString();                try        {            mDepthZ = (float)Integer.parseInt(string);            //mDepthZ = Math.min(mDepthZ, 300.0f);        }        catch (Exception e)        {            e.printStackTrace();        }    }        private void applyRotation(View animView, float startAngle, float toAngle)    {        float centerX = mCenterX;        float centerY = mCenterY;        Rotate3dAnimation rotation = new Rotate3dAnimation(                startAngle, toAngle, centerX, centerY, mDepthZ, true);        rotation.setDuration(mDuration);        rotation.setFillAfter(true);        rotation.setInterpolator(new AccelerateInterpolator());        rotation.setAnimationListener(new DisplayNextView());                animView.startAnimation(rotation);    }        /**     * This class listens for the end of the first half of the animation.     * It then posts a new action that effectively swaps the views when the container     * is rotated 90 degrees and thus invisible.     */    private final class DisplayNextView implements Animation.AnimationListener {        public void onAnimationStart(Animation animation) {        }        public void onAnimationEnd(Animation animation) {                        mContainer.post(new SwapViews());        }        public void onAnimationRepeat(Animation animation) {        }    }        private final class SwapViews implements Runnable    {        @Override        public void run()        {            mImageView1.setVisibility(View.GONE);            mImageView2.setVisibility(View.GONE);                        mIndex++;            if (0 == mIndex % 2)            {                mStartAnimView = mImageView1;            }            else            {                mStartAnimView = mImageView2;            }                        mStartAnimView.setVisibility(View.VISIBLE);            mStartAnimView.requestFocus();                        Rotate3dAnimation rotation = new Rotate3dAnimation(                    -90,                     0,                     mCenterX,                    mCenterY, mDepthZ, false);                        rotation.setDuration(mDuration);            rotation.setFillAfter(true);            rotation.setInterpolator(new DecelerateInterpolator());            mStartAnimView.startAnimation(rotation);        }    }}

rotate_anim.xml

Rotate3dAnimation.java

package com.nj1s.lib.anim;import android.graphics.Camera;import android.graphics.Matrix;import android.view.animation.Animation;import android.view.animation.Transformation;/** * An animation that rotates the view on the Y axis between two specified angles. * This animation also adds a translation on the Z axis (depth) to improve the effect. */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;    /**     * Creates a new 3D rotation on the Y axis. The rotation is defined by its     * start angle and its end angle. Both angles are in degrees. The rotation     * is performed around a center point on the 2D space, definied by a pair     * of X and Y coordinates, called centerX and centerY. When the animation     * starts, a translation on the Z axis (depth) is performed. The length     * of the translation can be specified, as well as whether the translation     * should be reversed in time.     *     * @param fromDegrees the start angle of the 3D rotation     * @param toDegrees the end angle of the 3D rotation     * @param centerX the X center of the 3D rotation     * @param centerY the Y center of the 3D rotation     * @param reverse true if the translation should be reversed, false otherwise     */    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);    }}

转载于:https://my.oschina.net/u/874134/blog/178343

你可能感兴趣的文章
Oracle数据库的备份方法
查看>>
Selenium 自动登录考勤系统
查看>>
关于如何以编程的方式执行TestNG
查看>>
智能照明造福千家万户 家居智能不再是梦
查看>>
物联网如何跳出“看起来很美”?
查看>>
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.6 UDP回射客户程序:dg_cli函数...
查看>>
不要将时间浪费到编写完美代码上
查看>>
《第一桶金怎么赚——淘宝开店创业致富一册通》一一第1章 创业梦想,怎样起步...
查看>>
基于容器服务的持续集成与云端交付(三)- 从零搭建持续交付系统
查看>>
《算法基础:打开算法之门》一3.4 归并排序
查看>>
高德开放平台开放源代码 鼓励开发者创新
查看>>
《高并发Oracle数据库系统的架构与设计》一2.5 索引维护
查看>>
《Exchange Server 2010 SP1/SP2管理实践》——2.4 部署外部网络环境
查看>>
Firefox 是 Pwn2own 2014 上攻陷次数最多的浏览器
查看>>
阿里感悟(十八)- 应届生Review
查看>>
《计算广告:互联网商业变现的市场与技术》一第一部分 在线广告市场与背景...
查看>>
话说模式匹配(5) for表达式中的模式匹配
查看>>