2019独角兽企业重金招聘Python工程师标准>>>
首先,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<