仿QQ的侧滑和侧拉删“事件拦截”的解决和优化
来源:互联网 发布:cogs mac 编辑:程序博客网 时间:2024/06/02 03:06
前三天已经完成了对高仿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); }
好了,第二个问题也解决了,小白在运行的时候正常。(如果有疑问或者见解,可以交流)
优化三:当我向上滑动的时候,我要把侧拉出来的恢复如初
这个就很简单了,我们只需要监听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(); } } });
说明一下:
好了,优化三已经解决,
优化四:当侧滑出来的时候,主面板左上角的头像是慢慢消失的
这个就很简单了,首先我们要获取到头像的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
项目效果图:
- 仿QQ的侧滑和侧拉删“事件拦截”的解决和优化
- 仿QQ侧滑删除,Listview上下滑动,Listview的iteam的点击事件等bug的解决
- 仿今日头条和qq侧滑和智慧北京的小项目 1
- 仿今日头条和qq侧滑和智慧北京的小项目 2
- 仿今日头条和qq侧滑和智慧北京的小项目 3
- 仿QQ侧滑和酷狗侧滑效果
- Hiberanate的拦截器和监听事件
- View和ViewGroup的事件拦截机制
- Android事件的分发、拦截和执行
- Android事件的分发、拦截和执行
- 仿QQ侧滑删除的ListView
- Android高仿IOS和QQ的弹出对话框
- 用popupwindow和selector实现仿qq的下拉菜单
- 高仿QQ首页消息和电话切换的实现
- 仿QQ侧滑菜单,HorizontalScrollView和DrawerLayout实现对比
- 仿QQ和仿网易新闻侧滑功能代码初识
- Android中View的事件分发和拦截机制
- Android 中触摸事件的分发和拦截
- iOS推送证书生成
- MySQL日期时间函数大全(咋个办呢 zgbn)
- (11)shell case esac语句
- Proguard混淆代码导致Spring自动装配失败
- mybatis与spring整合
- 仿QQ的侧滑和侧拉删“事件拦截”的解决和优化
- AVAudioRecord录音,AVAudioPlayer播放音频
- 什么时候使用 weak和unowned
- Awk 使用说明
- host ip is not allowed to connect to this MySql server解决方案
- Video of Nanjing receives millions of hits
- 阅读《Android 从入门到精通》(22)——网格视图
- java 常用工具类
- InputStream与String/byte[]相互转换