• 仿QQ的側滑和側拉删“事件拦截”的解决和优化


    前三天已经完毕了对高仿QQ的側滑菜单,側拉删除等做了实现和优化。如有兴趣能够看下:仿QQ6.0側滑之ViewDragHelper的使用(一)高仿QQ6.0側滑菜单之滑动优化(二)还有高仿QQ6.0之側滑删除

    说在前面

    今天的总结,是对前几天的一个补充。也就是有人问到的“事件拦截”的一些。有关事件拦截。后期会有相关的总结,今天先来解决一下的几个冲突:

    • 冲突一:側拉删除能够一次側拉出好多个(需求是一个)
    • 冲突二:当我側拉取消的时候,側滑也能跟出来(事件拦截)
    • 优化三:当我向上滑动的时候。我要把側拉出来的恢复如初
    • 优化四:当側滑出来的时候,主面板左上角的头像是慢慢消失的

    好了。既然已经知道了问题那我们就来一个一个的解决吧,哈哈,事实上也是不难的哈。请听小白我一一的给分析一下:

    冲突一:側拉删除能够一次側拉出好多个(需求是一个)

    • 1、分析解决原理 我们能够定义一个集合去存储拉出item的条目
    • 2、每次在去拉出其它item的时候。我们取遍历集合,假设个数大于等于1,就移除集合然后在实现拉出item

    由于我们在写SwipeLayout的时候。我们对外提供了几个状态方法,这个时候我们仅仅要得到其对象,然后调用方法就能够了(这里我用的是recycleview,listview的优化也在github上面,仅仅只是我没实用到而已)。

    我们在ItemRecycleAdapter.java中定义一个集合:

      private List<SwipeLayout> openItems;
    
    
    /**
         * 关闭全部的layout
         */
        public void closeAllLayout() {
            if (openItems.size() == 0)
                return;
            for (SwipeLayout l : openItems) {
                l.close();
            }
            openItems.clear();
        }
    

    在onBindViewHolder()方法中得到SwipeLayout对象:

     SwipeLayout swipeLayout = (SwipeLayout) holder.itemView;

    然后我们能够调用SwipeLayout 对外公开的方法:

    swipeLayout.setSwipeLayoutListener(new SwipeLayout.OnSwipeLayoutListener() {
                @Override
                public void onClose(SwipeLayout mSwipeLayout) {
                    //移除
                    openItems.remove(mSwipeLayout);
    
                }
    
                @Override
                public void onOpen(SwipeLayout mSwipeLayout) {
                     //加入
                    openItems.add(mSwipeLayout);
                }
    
                @Override
                public void onDraging(SwipeLayout mSwipeLayout) {
    
                }
    
                @Override
                public void onStartClose(SwipeLayout mSwipeLayout) {
    
                }
    
                @Override
                public void onStartOpen(SwipeLayout mSwipeLayout) {
    
                    //先去关闭打开的(假设没有打开的直接返回)
                    closeAllLayout();
                    openItems.add(mSwipeLayout);
                }
            });

    这样就能解决側拉删除能够一次側拉出好多个(需求是一个)问题了。

    冲突二:当我側拉取消的时候,側滑也能跟出来(事件拦截)

    这个也非常好解决,问题出现的原因就是,側拉和側滑都想去拦截事件,系统不知道该分发给谁去拦截,从而导致了错乱现象。


    解决思路:

    • 1、当有item出来的时候,让SwipeLayout恢复的时候去拦截事件
    • 2、加入一个个数集合(记录SwipeLayout拉出的个数)
    • 3、去DragLayout的onInterceptTouchEvent()方法中去处理是否拦截

    思路已经有了。而且这个集合我们也已经创建好了,这个时候我们仅仅须要提供一个得到集合个数的方法。ItemRecycleAdapter.java内部方法:

     public int getOpenItems() {
            return openItems.size();
        }

    当然了,尽管方法我们提供了,可是要得SwipeLayout能够拿得到这种方法才干去推断啊。这个我们能够在SwipeLayout中定义一个方法,传入ItemRecycleAdapter对象。由于ItemRecycleAdapter的对象能够取得这个获取个数的方法。

    那就得在一下两处进行改变:
    DragLayout.java中定义下面方法:

     public void setAdapterInterface(ItemRecycleAdapter adapter) {
            this.adapter = adapter;
        }

    我们在MainActivity.java中得到DragLayout的对象去传入进去就可以:

     //dl是DragLayout的实例化对象
     dl.setAdapterInterface(adapter);

    然后再DragLayout中的事件分发方法中去推断:

     private ItemRecycleAdapter adapter;
    
        float mDownX ;
        /**
         * 2、传递触摸事件
         *
         * @param ev
         * @return
         */
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
    
            if(getStatus() == Status.CLOSE){
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //获取到按压的是否的x坐标
                        mDownX = ev.getRawX();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //假设在移动的时候,item打开的个数大于0。就不拦截事件
                        if(adapter.getOpenItems() > 0){
                            return false;
                        }
                        //假设是向左滑,就不拦截事件(不用推断也行)
                        float delta = ev.getRawX() - mDownX;
                        if(delta < 0){
                            return false;
                        }
                        break;
                    default:
                        mDownX = 0;
                        break;
                }
            }
            return mDragHelper.shouldInterceptTouchEvent(ev);
        }
    

    好了,第二个问题也攻克了,小白在执行的时候正常。(假设有疑问或者见解,能够交流)

    优化三:当我向上滑动的时候。我要把側拉出来的恢复如初

    这个就非常easy了,我们仅仅须要监听RecycleView的滑动事件。在滑动过程中去推断是否有item滑出。假设有就调用adapter.closeAllLayout()方法关闭:

     recycleview.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                }
    
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                        adapter.closeAllLayout();
                    }
                }
            });

    说明一下:

    好了。优化三已经解决。

    优化四:当側滑出来的时候,主面板左上角的头像是慢慢消失的

    这个就非常easy了,首先我们要获取到头像的id,然后在DragLayout的那几个回调方法的onDraging()方法中设置头像的Alpha值就能够了。

     /**
             * DragLayout的事件监听
             */
            dl.setDragStateListener(new DragLayout.OnDragStatusListener() {
                @Override
                public void onClose() {
    
                }
    
                @Override
                public void onOpen() {
                }
    
                @Override
                public void onDraging(float percent) {
    
                    //通过拖拽实现主界面的左上的头像的隐藏
                    ViewHelper.setAlpha(head, 1 - percent);
                }
            });
    
            head.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dl.open();
                }
            });
        }

    好了,今天的两个事件冲突和两个优化基本攻克了。今天本来想着是总结一下粘性小球的事件(就是未读消息的那种),可是我又想想,这么多的问题,不能积累到最后。(尽管我没工作)可是还是知道,做事情要一个一个的做。事情也是一件一件解决的,好了,这里附上已经更新的github该项目地址:https://github.com/wuyinlei/QQ6.0
    项目效果图:
    这里写图片描写叙述

  • 相关阅读:
    身体终于好了 敢大声说话 没事了
    网名 关于网名
    opencv学习20初探基本类型数据
    SQL语句精典收藏
    CodeSimth Update存储过程
    动态sql语句基本语法
    CodeSmith下载与生成存储过程的一个模板
    SQL SERVER的数据类型
    SQL语句精典收藏
    CodeSmith入门教程之编写数据库模板
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7223849.html
Copyright © 2020-2023  润新知