转载请注明出处:王亟亟的大牛之路
从4月28号到3号下午,今年这个5.1是历年来最忙的,没有之一。简直就是 “瞬间爆炸”,本来想电脑带回去学习学习的结果都在忙着家里的事,唉。。。。废话不多说我们来看下今天的内容。
标题描述的不算太抽象,还是补下效果图方便大家理解。
这图够大的,代码内容来源于Git也收录在我的收纳库里了,这里给出传送门,大家可以自行寻找:https://github.com/ddwhan0123/Useful-Open-Source-Android 名字叫 AndroidCubeDemo,原作者 geminiwen
ok,我们来看下他是如何实现的,先贴下包目录
如我们在标题里说的那样,并没头用Viewpager来做翻页的实现而是自定义了一个试图组,我们来读读源码看下是如何实现的(顺道,解释下Animation)
public class CubeLayout extends FrameLayout {
//插值器
private BaseInterpolator mInterpolator = new AccelerateDecelerateInterpolator();
public CubeLayout(Context context) {
this(context, null);
}
public CubeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CubeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//获取子控件
View foregroundView = getChildAt(0);
View backgroundView = getChildAt(1);
//翻出的动画
CubeLeftOutAnimation cubeLeftOutAnimation = new CubeLeftOutAnimation();
cubeLeftOutAnimation.setDuration(1000);
cubeLeftOutAnimation.setFillAfter(true);
//翻进的动画
CubeRightInAnimation cubeRightInAnimation = new CubeRightInAnimation();
cubeRightInAnimation.setDuration(1000);
cubeRightInAnimation.setFillAfter(true);
foregroundView.startAnimation(cubeLeftOutAnimation);
backgroundView.startAnimation(cubeRightInAnimation);
}
}
一个自定义的FrameLayout 在加载结束后启动动画,具体步骤已经标注,不多解释,再来看看动画。(定义的插值器作者没用,这里也不解释什么,在CubeLayout2有用到)
我们再来看下绿色从左到右出现的动画的实现
public class CubeLeftOutAnimation extends Animation{
//空间变换工具
private Camera mCamera;
//位图矩阵
private Matrix mMatrix;
private int mWidth;
private int mHeight;
private static final int sFinalDegree = 90;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mMatrix = new Matrix();
mWidth = width;
mHeight = height;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float rotate = (sFinalDegree - sFinalDegree * interpolatedTime);
//保存当前状态
mCamera.save();
//在x,y,z三位控件内进行平移
mCamera.translate((-mWidth * interpolatedTime), 0, 0);
//以(0.0)为中心,绕Y轴进行旋转
mCamera.rotateY(rotate);
//将camera产生的效果加诸于参数matrix上
mCamera.getMatrix(mMatrix);
// //在使用camera设置动画之前,进行了camera.save(),将状态恢复到保存的状态。
mCamera.restore();
//平移操作
mMatrix.postTranslate(mWidth, mHeight / 2);
mMatrix.preTranslate(0, -mHeight / 2);
t.getMatrix().postConcat(mMatrix);
}
}
继承了Animation 并实现 applyTransformation(float interpolatedTime, Transformation transformation)以及initialize(int width, int height, int parentWidth, int parentHeight) 方法
那他们分别是干什么的呢?
applyTransformation方法,这个方法是一个回调方法,在动画进行的过程中,系统会一直不停的调用这个方法,每次调用,这个方法给我们传进来一个变换矩阵,通过对这个矩阵的操作,我们就可以实现自己的动画效果了
interpolatedTime:该参数代表了时间的进行程度(如:你设置的时间是1000ms, 那么interploatedTime就会从0开始一直到1000)
transformation:代表补间动画在不同时刻对图形或组建的变形程度。
initialize做一些初始化的操作,例子里我们把回调来的参数做本地化处理。
具体的步骤在注释里已经写了,因为preTranslate 和postTranslate 还是有点搞脑子的,但是看了下面你就理解了
public boolean preTranslate (float dx, float dy)
Preconcats the matrix with the specified translation. M' = M * T(dx, dy)
public boolean postTranslate (float dx, float dy)
Postconcats the matrix with the specified translation. M' = T(dx, dy) * M
举个例子
(1)
matrxi.scale(0.8, 0.8);
matrix.preTranslate(1000, 0);
(2)
matrix.scale(0.8, 0.8);
matrix.postTranslate(1000, 0);
第一段代码缩放后会再平移1000*0.8=800的距离,而第二段代码缩放后会平移坐标给定的1000的距离。
是不是这么解释就理解了?!
PS:今天 上海 好热啊!!!!!靠
有疑问或者有活干可以微信我,广告的揍开!!