IReader打开书本,关闭书本动画的自定义控件

一,实现思路

实现的效果:此控件主要是模仿IReader打开书本翻转以及放大特效,在看文章之前可以找本书来翻转加深理解,呵呵,开个玩笑,进入正题。

实现的效果:

打开书本:

上层为cover,下层为content。cover播放放大翻转动画,content播放放大动画。

几个注意点:

1,动画的播放只能局限在父ViewGroup内部,放大到全屏该怎么进行?

A:使用克隆体添加到WindowManager中,然后去播放动画。

2,不能直接对WindowManager中的子控件播放动画,该怎么解决?

A:在WindowManger铺满一个AbsoluteLayout,然后再将克隆体cover添加到WindowManger中。

3,如果对任意位置的一张图片,放大到全屏,让位置刚好合适?

A:需要寻找到一个合适的缩放点。

二,具体实现

1,ContentScaleAnimation类,实现下层图片的缩放。如何寻找缩放点?

上图中

这里只演示怎么计算缩放点横坐标

x为缩放点横坐标

pw为parentWidth

ml为marginLeft

w为控件宽度

找到如下关系

缩放点到自身左边距离/缩放点到父控件左边的距离=缩放点自身右侧距离/缩放点到父控件右边的距离

(x-ml)/x=(w-(x-ml))/(pw-x)

计算得到x=ml*pw/(pw-w)

这里提供方法:

private float resolvePivotX(float margingLeft, int parentWidth, int width) {return (margingLeft * parentWidth) / (parentWidth – width);}

package huwei.com.bookviewdemo;import android.view.animation.Animation;import android.view.animation.Transformation;/** * Created by jayce on 15-2-4. */public class ContentScaleAnimation extends Animation {private final float mFromX;private final float mToX;private final float mFromY;private final float mToY;private float mPivotX;private float mPivotY;private float mPivotXValue;private float mPivotYValue;private boolean mReverse;public ContentScaleAnimation(float mFromX, float mToX, float mFromY, float mToY, float mPivotXValue, float mPivotYValue, boolean mReverse) {this.mFromX = mFromX;this.mToX = mToX;this.mFromY = mFromY;this.mToY = mToY;this.mPivotXValue = mPivotXValue;this.mPivotYValue = mPivotYValue;this.mReverse = mReverse;}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {float sx = 1.0f;float sy = 1.0f;if (mFromX != 1.0f || mToX != 1.0f) {sx = mReverse ? mToX + (mFromX – mToX) * interpolatedTime : mFromX + (mToX – mFromX) * interpolatedTime;}if (mFromY != 1.0f || mToY != 1.0f) {sy = mReverse ? mToY + (mFromY – mToY) * interpolatedTime : mFromY + (mToY – mFromY) * interpolatedTime;}if (mPivotX == 0 && mPivotY == 0) {t.getMatrix().setScale(sx, sy);} else {t.getMatrix().setScale(sx, sy, mPivotX, mPivotY);}}@Overridepublic void initialize(int width, int height, int parentWidth, int parentHeight) {super.initialize(width, height, parentWidth, parentHeight);mPivotX = resolvePivotX(mPivotXValue, parentWidth, width);mPivotY = resolvePivoY(mPivotYValue, parentHeight, height);}private float resolvePivotX(float margingLeft, int parentWidth, int width) {return (margingLeft * parentWidth) / (parentWidth – width);}private float resolvePivoY(float marginTop, int parentHeight, int height) {return (marginTop * parentHeight) / (parentHeight – height);}public void reverse() {mReverse = !mReverse;}public boolean getMReverse() {return mReverse;}}

,2,Rotate3DAnimation类,实现参考apiDemo中的Rotate3dAnimation,在此基础上进行修改,实现翻转和缩放动画。

这里需要绕Y轴旋转180度,在翻转前需要将物体移动到y轴上,然后再移回去。

matrix.preTranslate(-mPivotXValue, 0);//在进行rotateY之前需要移动物体,让物体左边与Y轴对齐matrix.postTranslate(mPivotXValue, 0);//还原物体位置package huwei.com.bookviewdemo;import android.graphics.Camera;import android.graphics.Matrix;import android.view.animation.Animation;import android.view.animation.Transformation;/** * @author jayce * @date 2015/2/3 */public class Rotate3DAnimation extends Animation {private Camera mCamera;private final float mFromDegrees;private final float mToDegrees;private final float mPivotXValue;private final float mPivotYValue;//private final float mDepthZ; //不需要用到此参数private final float scaleTimes;private boolean mReverse;private float mPivotX;//缩放点Xprivate float mPivotY;//缩放点Y/*** cover 动画构造方法,一边放大,,一边翻转* @param mFromDegrees* @param mToDegrees* @param mPivotXValue 控件左上角X* @param mPivotYValue 控件左上角Y* @param scaleTimes 缩放比例* @param mReverse 动画是否逆向进行*/public Rotate3DAnimation(float mFromDegrees, float mToDegrees, float mPivotXValue, float mPivotYValue, float scaleTimes, boolean mReverse) {this.mFromDegrees = mFromDegrees;this.mToDegrees = mToDegrees;this.mPivotXValue = mPivotXValue;this.mPivotYValue = mPivotYValue;this.scaleTimes = scaleTimes;this.mReverse = mReverse;}@Overridepublic void initialize(int width, int height, int parentWidth, int parentHeight) {super.initialize(width, height, parentWidth, parentHeight);mCamera = new Camera();mPivotX = resolvePivotX(mPivotXValue, parentWidth, width); //计算缩放点XmPivotY = resolvePivoY(mPivotYValue, parentHeight, height); //计算缩放点Y}/*** 执行顺序 matrix.preTranslate() –> camera.rotateY(degrees) –> matrix.postTranslate() –> matrix.postScale()* @param interpolatedTime* @param t*/@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {float degrees = mReverse ? mToDegrees + (mFromDegrees – mToDegrees) * interpolatedTime : mFromDegrees + (mToDegrees – mFromDegrees) * interpolatedTime;final Matrix matrix = t.getMatrix();final Camera camera = mCamera;camera.save();camera.rotateY(degrees);camera.getMatrix(matrix);camera.restore();matrix.preTranslate(-mPivotXValue, 0);//在进行rotateY之前需要移动物体,让物体左边与Y轴对齐matrix.postTranslate(mPivotXValue, 0);//还原物体位置if (mReverse) {matrix.postScale(1 + (scaleTimes – 1) * (1.0f – interpolatedTime), 1 + (scaleTimes – 1) * (1.0f – interpolatedTime), mPivotX, mPivotY);} else {matrix.postScale(1 + (scaleTimes – 1) * interpolatedTime, 1 + (scaleTimes – 1) * interpolatedTime, mPivotX, mPivotY);}}private float resolvePivotX(float margingLeft, int parentWidth, int width) {return (margingLeft * parentWidth) / (parentWidth – width);}private float resolvePivoY(float marginTop, int parentHeight, int height) {return (marginTop * parentHeight) / (parentHeight – height);}public void reverse() {mReverse = !mReverse;}public boolean getMReverse() {return mReverse;}}

下载地址

我希望你能知道,我的心永远只为你跳动。

IReader打开书本,关闭书本动画的自定义控件

相关文章:

你感兴趣的文章:

标签云: