android基于SwipeRefreshLayout实现类QQ的侧滑删除

前言

记得去年做一个聊天项目需要实现类似QQ的下拉刷新并且有侧滑删除的功能,在网上找了很久都没有QQ的完美,多多少少存在各种的问题,最后把下拉刷新的功能去掉后,只保留了侧滑删除的功能才找到个完美的。回去后和一朋友讨论,朋友找了以后说了一句,这种功能没有8K以上的是写不出来的(⊙﹏⊙)b。现在看来当时真的太天真了。而如今自己也没有8K还是尝试去写写,顺便当练练手。

还是效果图优先

效果图当中看不出来事件滑动的解决方案(或者是我不会如何录制手指在屏幕上滑动方向和点击,知道的大神请告诉下,谢谢)具体的可以去下方的GitHub上下载看。

还是先看怎么用

首先传送门地址 SwipeMenuRefreshView

此项目中引用了一个侧滑菜单的库具体的地址 AndroidSwipeLayout (这是一个非常强大的库可以上下左右的滑动展示,具体可以去其GitHub上了解)

引用

compile 'com.nero.ren:SwipeMenu:1.2.0'

布局文件

<ren.widget.refresh.SwipeMenuRefreshView android:id="@+id/refresh" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" /> </ren.widget.refresh.SwipeMenuRefreshView>

Item布局文件

<com.daimajia.swipe.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="80dp" app:clickToClose="true"> //侧滑出来的布局 <LinearLayout android:id="@+id/bottom_wrapper_2" android:layout_width="wrap_content" android:layout_height="80dp" android:tag="Bottom4"> <TextView android:id="@+id/top" android:layout_width="70dp" android:layout_height="match_parent" android:background="#cfcfcf" android:gravity="center" android:text="置顶" /> <TextView android:id="@+id/noread" android:layout_width="100dp" android:layout_height="match_parent" android:background="#ffa500" android:gravity="center" android:text="标记未读" /> <TextView android:id="@+id/delete" android:layout_width="70dp" android:layout_height="match_parent" android:background="#FF0000" android:gravity="center" android:text="删除" /> </LinearLayout> //默认展示的布局 <RelativeLayout android:layout_width="match_parent" android:layout_height="80dp"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="aaaaa" android:textSize="18sp" /> </RelativeLayout> </com.daimajia.swipe.SwipeLayout>

具体实现

1、实现思路

思路其实也很简单就是在实现自定义SwipeRefreshLayout重写onInterceptTouchEvent根据左右还是上下滑动进行事件的拦截和下发

2、判断滑动方向

主要根据用户滑动的夹角来判断是上下滑动还是左右滑动。判断后设置一个标记,下一次滑动的时候如果上下滑动(Listiview)的滑动那么就调用父类的的onInterceptTouchEvent方法正常滑动,此时事件在到达侧滑菜单的时候已经被消费了所有不会滑出侧滑菜单。如果是左右滑动则return false 不拦截事件交由子控件处理,这是左右滑动Listview是不会做消费所以会到达让侧滑菜单来处理。

case MotionEvent.ACTION_DOWN: pressX = (int) ev.getX(); //记录按下的X坐标 pressY = (int) ev.getY();//记录按下的Y坐标 break; case MotionEvent.ACTION_MOVE: //判断滑动距离是否是正常的滑动 if (Math.abs(ev.getY() - pressY) < touchSlop && Math.abs(ev.getX() - pressX) < touchSlop) return super.onInterceptTouchEvent(ev); //如果用户是滑动listview则交由父类onInterceptTouchEvent处理 if (interceptStatus == REFRESH_STATUS) return super.onInterceptTouchEvent(ev); //用户如果是滑出SwipeLayout则不拦截时间交由SwipeLayout处理 else if (interceptStatus == SWIPE_MENU_OPEN) return false; //根据滑动角度判断用户是滑出SwipeLayout还是Listview double angle = Math.atan((ev.getY() - pressY) / (ev.getX() - pressX));//计算滑动的角度 int degrees = (int) Math.toDegrees(angle); degrees = Math.abs(degrees); //大于45度则判断为Listview滑动 if (degrees > 45) { Log.d(TAG, "正在上下滑动"); //如果当前是SwipeLayout内点击的事件序列则不允许滑动 if (interceptStatus == SWIPE_MENU_CLOSE) return true; interceptStatus = REFRESH_STATUS; //标记为Listview滑动 return super.onInterceptTouchEvent(ev); } else { //小于45度则判断为SwipeLayout滑动 Log.e(TAG, "正在左右滑动"); currentSwipeLayout = getCurrentSwipeLayout(); //获取当前滑出的SwipeLayout interceptStatus = SWIPE_MENU_OPEN; //标记为SwipeLayout滑动 return false; }

3点击事件处理

点击事件分为几种情况

1.用户普通的item点击:此情况下不做任何处理

2.当滑出侧滑菜单栏以后,点击其他的item时,这是判断是否是当前滑出的侧滑菜单的position如若不是在down事件的时候变将其关闭并且 return true当在onInterceptTouchEvent中retur true 后此后所有的事件,直到手指抬起时的所有操作都交由自身的onTouchEvent处理而在onTouchEvent中也不做任何操作直接拦截即可达到需要的效果

判断是否是点击的当前滑出菜单的Item

if (currentSwipeLayout != null && currentSwipeLayout.getOpenStatus() != SwipeLayout.Status.Close) { //如果当前有打开或者正在打开的SwipeLayout Log.d(TAG, "currentSwipeLayout.getOpenStatus() " + currentSwipeLayout.getOpenStatus()); interceptStatus = SWIPE_MENU_CLOSE;//此次用户操作为关闭SwipeLayout Rect rect = new Rect(); currentSwipeLayout.getHitRect(rect); //判断当前点击X Y坐标是否在当前SwipeLayout中,即用户是否点击这个SwipeLayout,有就不拦截时间交由SwipeLayout自己处理 if (rect.contains(pressX, pressY)) { return false; } onInterceptTouchEvent中down事件 case MotionEvent.ACTION_DOWN: //如果没有就关闭并且拦截此时间顺序中所有事件 currentSwipeLayout.close(); return true; onTouchEvent中的move事件 case MotionEvent.ACTION_MOVE: if (interceptStatus == SWIPE_MENU_CLOSE)//如果是SwipeLayout关闭事件序列则拦截事件 return true;

3.当用户点击的是当前侧滑菜单,这里又有两种情况如果点击的范围不是侧滑菜单的范围则return false这时如果抬手时是在侧滑菜单的范围内将会触发点击事件(如果有)如果没有在此范围则关闭侧滑菜单。如果此期间有move事件即用户有滑动会进入之前说的move判断逻辑。

简而言之就是按下的范围是滑出侧滑菜单的Item则不拦截交由儿子你说了算,如果有滑动就由父类进行开始说的判断,然后进行相应逻辑,此时就不是儿子说了算。

//判断当前点击X Y坐标是否在当前SwipeLayout中,即用户是否点击这个SwipeLayout,有就不拦截时间交由SwipeLayout自己处理 if (rect.contains(pressX, pressY)) { return false; } //如果没有就关闭并且拦截此时间顺序中所有事件 currentSwipeLayout.close(); return true;

结语

此文设计事件分发的许多知识,加上这几个控件都有自己的方法所有有许多内容不太容易说的清楚(甚至自己都不一定弄的很清楚)加之本人表达能力不算好,所以可能云里雾里的,如果有兴趣的朋友们可以去GitHub下载源码看看。最后在给一次地址 SwipeMenuRefreshView

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-10 06:39:10

android基于SwipeRefreshLayout实现类QQ的侧滑删除的相关文章

Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果_Android

本文实例讲述了Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果.分享给大家供大家参考,具体如下: 1. 滚动加载 listView.setOnScrollListener(new OnScrollListener() { //添加滚动条滚到最底部,加载余下的元素 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScro

Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果

本文实例讲述了Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果.分享给大家供大家参考,具体如下: 1. 滚动加载 listView.setOnScrollListener(new OnScrollListener() { //添加滚动条滚到最底部,加载余下的元素 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScro

Android使用SwipeListView实现类似QQ的滑动删除效果_Android

QQ的滑动删除效果很不错,要实现这种效果,可以使用SwipeListView. 1. 下载com.fortysevendeg.swipelistview这个项目(以前GitHub上有,现在GitHub上没有了,百度了很多次才下载到的),导入Eclipse,右键单击,选择Properties->Android,选中Library下面的IsLibrary. 2. 新建一个项目MySwipeListView,加入SwipeListView这个库. 3. 在主窗体里面放入一个SwipeListView控

Android recyclerview实现拖拽排序和侧滑删除

Recyclerview现在基本已经替代Listview了,RecyclerView也越来越好用了  当我们有实现条目的拖拽排序和侧滑删除时  可以直接时候Recyclerview提供的API就可以直接实现了 先贴上主要代码 private void initveiw() { ArrayList<String> items = new ArrayList<>(Arrays.asList("itme1", "item2", "itme

Android使用DrawerLayout实现仿QQ双向侧滑菜单_Android

1.概述 之前写了一个Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 ,恰逢QQ5.2又加了一个右侧菜单,刚好看了下DrawerLayout,一方面官方的东西,我都比较感兴趣:另一方面,这玩意用起来的确方便,于是简单写了个demo,高仿QQ5.2双向侧滑,分享给大家. 首先看看效果图: DrawerLayout用起来真的很方便,下面一起看看用法~ 2.DrawerLayout的使用 直接将DrawerLayout作为根布局,然后其内部第一个View为内容区域,第二个View为左侧

Android使用DrawerLayout实现仿QQ双向侧滑菜单

1.概述 之前写了一个Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 ,恰逢QQ5.2又加了一个右侧菜单,刚好看了下DrawerLayout,一方面官方的东西,我都比较感兴趣:另一方面,这玩意用起来的确方便,于是简单写了个demo,高仿QQ5.2双向侧滑,分享给大家. 首先看看效果图: DrawerLayout用起来真的很方便,下面一起看看用法~ 2.DrawerLayout的使用 直接将DrawerLayout作为根布局,然后其内部第一个View为内容区域,第二个View为左侧

Android App中ListView仿QQ实现滑动删除效果的要点解析_Android

本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示.但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制.所以决定继承ListView然后结合PopupWindow. 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=

Android App中ListView仿QQ实现滑动删除效果的要点解析

本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示.但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制.所以决定继承ListView然后结合PopupWindow. 首先是布局文件: delete_btn.xml:这里只需要一个Button <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=

Android自定义view系列之99.99%实现QQ侧滑删除效果实例代码详解

首先声明本文是基于GitHub上"baoyongzhang"的SwipeMenuListView修改而来,该项目地址: https://github.com/baoyongzhang/SwipeMenuListView 可以说这个侧滑删除效果是我见过效果最好且比较灵活的项目,没有之一!!! 但是在使用它之前需要给大家提两点注意事项: 1,该项目支持Gradle dependence,但是目前作者提供的依赖地址对应的项目不是最新的项目,依赖过后的代码与demo中使用的不一致,会提示没有B