遇一需求,要求实现列表项3D的滚动效果,用来实现滚动新闻。完成后如下图所示效果:
在这里,使用的是比较简单的实现方法,使用apidemos中的Rotate3dAnimation类。
我们来查看这个类的applyTransformation方法,该方法是执行动画的主要方法。其中代码如下:
@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);
}
其中第一行获得原始角度,第二行代码通过算法得到将要翻转的角度。这里需要说明的是,该类使用Camera来做简单的动画效果。
Camera给我的理解是,对当前对象进行拍摄快照。后得到Transformation的矩阵,重点是下面的这句:
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
我们查看api得知,translate的三个参数分别用于对对象进行x、y、z三轴上的平移,因此,此处的代码为在z轴上进行平移,这句代码也使得我们的动画具有3D投影效果,因此是必须的。
下面就是重新获得矩阵,保存及矩阵转换了。使用起来还是比较简单的。
这里使用,最重要的是在创建动画对象时,进行中心点赋值。如果值错了,那动画将千差万别。具我所研究,这里的坐标设置为屏幕左上角为原点,当前屏幕为整个坐标系中的第三象限,因此在算Y轴坐标时,有时需要格外注意不是加,而是减。
好了,就说到这里。提醒大家不要怀疑这个工具类的代码。如果你的动画位置不对了,或不是你想要的效果了,那肯定是你的中心点设错了。另外有空研究下OpenGL吧。