ITPub博客

首页 > IT职业 > IT职场 > 从零开始打造一个Android 3D立体旋转容器

从零开始打造一个Android 3D立体旋转容器

IT职场 作者:mex 时间:2021-09-09 09:29:17 0 删除 编辑

原文链接

1.概述

回到正题,这次带来的效果,是一个Android 的3D立体旋转的效果。

当然灵感的来源,来自早些时间微博上看到的效果图。

非常酷有木有!作为程序猿我当然要把它加入我的下一个项目中啦!

原效果

图片描述

我们实现的效果:

(为了更加可定制化,我在原图基础上新增了新的效果)

图片描述

可以快速滚动,并且无限循环

图片描述

这个是对一些参数的进行设定

图片描述

对图片的包裹效果

图片描述

因为本身继承自ViewGroup,所以基本控件都是可以包裹的

https://github.com/ImmortalZ/StereoView

通过我们实现的效果图可以发现:

1.切换的时候是一个3D立体的效果

2.布局中的每一个Item可以自由切换,且无限循环滚动

要解决上面的效果,我们需要什么技术点呢?

1.要想实现一个3D效果,我们可以借助Android中的Camera、Matrix

2.要想实现滚动,毫无疑问,我们需要借助Scroller

当然一切看起来很简单,其实不然,除此之外,你还需要对于滑动冲突进行处理等等,下面我开始介绍啦。

这就是我们这次项目的大致

图片描述

http://blog.csdn.net/rav009/article/details/7763223 ( Android postTranslate和preTranslate的理解)

不过对于Camera的坐标系我还有一点点疑问,我准备有机会写一篇关于Camera和Matrix文章。

3.3 滑动事件冲突的处理

完成上面两个步骤,那么我们就算Over了吗?

不!还有很重要的一点,就是事件冲突的处理。 举个例子:我们把手放到我们的容器上,系统怎么知道我们这个滑动事件是给容器还是要给容器的子类的呢?

(给容器自己,则进行滑动的操作,给容器的子类,则容器的子类可以进行点击事件的判断处理)

对于这种情况,我就很大度啦,全部交给容器子类处理!子类不要,OK,那容器你自己拿来玩吧。

————之所以不走寻常路:交给容器处理,容器不需要再交给子类

原因在于:容器拿到滑动事件只需要做滑动操作,而子类则不同,它有点击事件需要判断,一个容器有很多子类,而很多子类只有一个共同的容器,如果把控制权交给容器,那么容器怎么可能能够判断得出不同的子类到底需不需要这个滑动事件呢?所以,既然这么麻烦,那么统统交给子类处理。

交给子类处理,则容器中onInterceptTouchEvent需要做如下操作

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {        if (ev.getAction() == MotionEvent.ACTION_DOWN) {            return false;
        }        return true;
    }

而子类(用CustomEdittext为例)的dispatchTouchEvent需要做如下判断

@Override    public boolean dispatchTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);                break;            case MotionEvent.ACTION_MOVE:                if (!isContain(event)) {                    //子类不需要,交给容器自己处理
                    getParent().requestDisallowInterceptTouchEvent(false);
                    setFocusable(false);
                } else {                    //子类自己做操作
                    setFocusableInTouchMode(true);
                }                break;            case MotionEvent.ACTION_UP:                break;
        }        return super.dispatchTouchEvent(event);
    }

在isContain中,我做的是点击的坐标是否在Edittext中,在则拦截,子类处理,不在,则交给父类容器

 private boolean isContain(MotionEvent event) {
        region.set(rect);        if (region.contains((int) event.getX(), (int) event.getY())) {            return true;
        }        return false;
    }

当然交给子类这样也导致了一个问题,就是我如果需要给容器中的子类进行点击事件,则都需要自定义一个View(例如上面的CustomEdittext 继承自Edittext)。

例如我就自定义了三个View,不过还是很简单的,几分钟的事就搞定了(在自定义View中dispatchTouchEvent进行判断)。

具体的可以参考代码。

图片描述

3.4 点击水纹波效果

细心的人会发现,我这里还有个RippleView。
没错这就是点击后有水纹波的效果。
Android本身可以在XML中用ripple实现,不过是Android 5.0以上,个人觉得兼容性不太好,就自己随便写了一个简易的,哈哈,效率不能保证,各位看客看看就好啦。

https://github.com/ImmortalZ/StereoView


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3932/viewspace-2810172/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-07-09

  • 博文量
    193
  • 访问量
    1886