Android新姿势:3D翻转效果原理

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

首先,android里是没有3D翻转的动画效果的,但是呢,android有提供一个Camera的类,可以利用这个类来实现。


先看代码,Rotate3d是继承了Animation的一个动画类,多余的代码我就不给出了,只看applyTransformation方法内是怎么实现的。

public class Rotate3d extends Animation {

    ...

        @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();

                // 左右翻转

camera.rotateY(degrees);

// 取得变换后的矩阵

camera.getMatrix(matrix);

camera.restore();


matrix.preTranslate(-centerX, -centerY);

matrix.postTranslate(centerX, centerY);

        } 

    ...


接下来解析下原理。

1、先获取视图的Matrix:

    final Matrix matrix = t.getMatrix();

2、利用camera改变matrix的参数:

    camera.rotateY(degrees);//翻转一定的角度

    camera.getMatrix(matrix);//改变matrix


 PS:注意这里是用getMatrix的方法来改变,顺便普及一下小知识,java的方法传入的参数如果是对象的话,是可以在方法内改变对象的属性值的;不过如果传入的是一个int、float、String之类的基础类型,则不会改变。举例:

    假如有个方法 set(int i){ i++; } 然后用了 int i=3; set(i); 这时打印出的 i 还是3。

    但是 假如有个方法 set(C c){ c.i++; } 然后用了 c = new C(); c.i=3; set(c); 这时打印出 c 对象的 i 就是4了。 


3、继续,一般上面的步骤已经可以见到3D翻转效果了,但是很难看,因为这种翻转是没有中心点的,接下来就是将翻转后的视图弄到一个位置上去(其实这么说也不太对)。

    matrix.preTranslate(-centerX, -centerY);

    matrix.postTranslate(centerX, centerY);

这个的话其实我也研究了好久最后没研究出个所以然来,反正记住这样写就可以设置以某个坐标为中心进行翻转了。 



---------------------------我叫分割线-------------------------- 


最近搞的一个项目需要用到有3D翻转效果的gallery,卡了我好久。


上面给出的代码是制作一个3D翻转的动画效果,但是如果要在gallery中用到这种动画效果的话自然不行。主要是翻转角度的计算问题。


animation动画类中可以根据动画发生的时间点来计算角度,而gallery就不行,因为gallery是随手势滑动发生动画的,时间不固定,还可以左右来回滑动。


不过只要解决了角度的问题,3D翻转效果自然不是问题。先看代码。

@Override

protected boolean getChildStaticTransformation(View child, Transformation t) {

final float centerX = App.width / 2;

final float centerY = App.height / 2;

final Camera camera = mCamera;


camera.save();

float rotate = -child.getLeft() * 90 / 480;

camera.rotateY(rotate);

camera.getMatrix(t.getMatrix());

camera.restore();


t.getMatrix().preTranslate(-centerX, -centerY);

t.getMatrix().postTranslate(centerX, centerY);

   return true; 

}

这是重写gallery的一个方法,具体的角度计算,其实就是根据当前视图View child与左屏幕的距离来计算(也可以当成是x坐标)。


好~效果出来了!还是挺有成就感的~~ >v<


转载于:https://my.oschina.net/u/816576/blog/345785

你可能感兴趣的:(Android新姿势:3D翻转效果原理)