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

 更新时间:2017年10月30日 16:25:06   作者:_独爱夜色  
本篇文章主要介绍了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

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

相关文章

  • Kotlin函数式编程超详细介绍

    Kotlin函数式编程超详细介绍

    一个函数式应用通常由三大类函数构成:变换transform、过滤filters合并combineo每类函数都针对集合数据类型设计,目标是产生一个最终结果。函数式编程用到的函数生来都是可组合的,也就是说,你可以组合多个简单函数来构建复杂的计算行为
    2022-09-09
  • Android修改自己程序字体的方法详解

    Android修改自己程序字体的方法详解

    本篇文章是对Android修改自己程序字体的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 往Android系统中添加服务的方法教程

    往Android系统中添加服务的方法教程

    最近因为平台升级,需要在系统中添加一些服务,所以将整个过程总结一下,下面这篇文章主要给大家介绍了往Android系统中添加服务的方法教程,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-05-05
  • Android 防止过快(多次)点击的实现方法

    Android 防止过快(多次)点击的实现方法

    很多用户经常会出现过快且多次点击同一按钮的情况,本篇文章主要介绍了Android 防止过快点击的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Android隐藏标题状态栏的方法

    Android隐藏标题状态栏的方法

    这篇文章主要介绍了Android隐藏标题状态栏的方法的相关资料,需要的朋友可以参考下
    2016-01-01
  • android教程之textview解析带图片的html示例

    android教程之textview解析带图片的html示例

    本文介绍的示例适用于android中需要解析带图片的htlm数据,需要的朋友可以参考下
    2014-02-02
  • Android开发常用经典代码段集锦

    Android开发常用经典代码段集锦

    这篇文章主要介绍了Android开发常用经典代码段,涉及Android开发过程中针对手机、联系人、图片、存储卡等的相关操作技巧,非常简单实用,需要的朋友可以参考下
    2016-02-02
  • Android SharedPreferences数据存储详解

    Android SharedPreferences数据存储详解

    SharedPreferences是安卓平台上一个轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中;当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出
    2022-11-11
  • Android对EditTex的图片实现监听

    Android对EditTex的图片实现监听

    这篇文章主要为大家详细介绍了Android如何对EditTex的图片实现监听,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • android使用Jsoup 抓取页面的数据

    android使用Jsoup 抓取页面的数据

    本篇文章主要介绍了android使用Jsoup 抓取页面的数据,jsoup 是一款Java的HTML解析器,有需要的朋友可以了解一下。
    2016-11-11

最新评论