不用ViewPager一样做翻页,简单讲讲自定义3D动画

本文介绍了一种不用ViewPager实现3D翻页效果的方法,通过自定义视图组和动画。作者分享了一个Android项目的GitHub链接,详细解读了动画的实现原理,包括applyTransformation和initialize方法的作用,并通过实例解释了预翻译和平移的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:王亟亟的大牛之路

从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:今天 上海 好热啊!!!!!靠

有疑问或者有活干可以微信我,广告的揍开!!

这里写图片描述

这里写图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值