【Android 事件分发】ItemTouchHelper 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )_android itemtouchhelper_韩曙亮的博客-程序员秘密

技术标签: 事件分发  android  Android 事件分发  

Android 事件分发 系列文章目录


【Android 事件分发】事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 )
【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

【Android 事件分发】ItemTouchHelper 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )
【Android 事件分发】ItemTouchHelper 实现侧滑删除 ( 设置滑动方向 | 启用滑动操作 | 滑动距离判定 | 滑动速度判定 | 设置动画时间 | 设置侧滑触发操作 )
【Android 事件分发】ItemTouchHelper 实现拖动排序 ( 设置滑动方向 | 启启用长按拖动功能 | 拖动距离判定 | 设置拖动触发操作 )






一、ItemTouchHandler 简介



ItemTouchHandler 是 Google 提供的一个工具类 , 主要针对 RecyclerView 的上下左右拖动事件 进行处理 ;

如 : 侧滑删除 功能 , 条目位置拖动交换 功能 , 就可以使用 ItemTouchHandler 实现 ;


如果 RecyclerView 没有添加 ItemTouchHandler , 只能上下滚动 , 左右拉动 , 没有效果 , 也无法进行拖动交换条目操作 ;

调用 ItemTouchHandler 的 attachToRecyclerView 方法 , 传入想要添加上下左右拖动事件的 RecyclerView 对象 , 即可为该 RecyclerView 添加拖动事件 ;

添加后 , 该 RecyclerView 自动可以进行上下左右拖动操作 , 用户可以自行添加相关的回调 ItemTouchHelper.Callback , 响应这些事件 ;


初始化 RecyclerView 并设置 ItemTouchHelper 示例 :

        //1 . 从布局中获取 RecyclerView
        recycler_view = findViewById(R.id.recycler_view);

        //2 . 创建并设置布局管理器
        //创建布局管理器
        layoutManager = new LinearLayoutManager(
                this,
                RecyclerView.VERTICAL,
                false);

        //设置布局管理器
        recycler_view.setLayoutManager(layoutManager);

        // 设置边距
        recycler_view.addItemDecoration(new ItemDecoration());

        //3 . 创建并设置列表适配器
        adapter = new Adapter();
        recycler_view.setAdapter(adapter);

        //4. 添加拖动事件
        Callback callback = new Callback();
        mItemTouchHelper = new ItemTouchHelper(callback);
        mItemTouchHelper.attachToRecyclerView(recycler_view);

效果展示 : 此时还没有加入上下左右 拖动/滑动 操作 ;

在这里插入图片描述





二、ItemTouchHelper.Callback 自定义实现



其中的 ItemTouchHelper.Callback 一般都需要开发者自定义子类实现 ;


1、设置移动标志 ( 拖动/滑动 )


重写 ItemTouchHelper.Callback 的 getMovementFlags 方法 ;

该方法用于设置上下左右动作 , 只有在此处打开了指定方向的设置 , 才可以应用具体方向的拖动 , 动作有两种 , 一种是滑动 , 如左右侧滑 ; 一种是拖动 , 长按后激活拖动操作 , 可用于拖动交换位置操作 ;

拖动 / 滑动 标志位可以使用 ItemTouchHelper.UP | ItemTouchHelper.DOWN , 或运算得到想要的标志位 ;

将或运算结果传入 makeMovementFlags 方法 , 第一个参数是设置拖动标志位 , 第二个参数是设置滑动标志位 ;


设置 左右滑动 , 上下拖动代码如下 :

    /**
     * 设置上下左右动作
     * 只有在此处打开了指定方向的设置 , 才可以应用具体方向的拖动
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
    
        /*
            设置拖动方向, 此处设置上下拖动事件
         */
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;

        /*
            设置滑动方向, 此处设置左右侧滑事件
         */
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

        // 应用 拖动 和 滑动 设置
        return makeMovementFlags(dragFlags, swipeFlags);
    }

效果展示 :

在这里插入图片描述





三、完整代码实现




1、主界面


package kim.hsl.recyclerview;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    

    /**
     * 数据源
     */
    private ArrayList<String> names = new ArrayList<String>();

    /**
     * 当前的 RecyclerView 列表
     */
    private RecyclerView recycler_view;

    /**
     * 布局管理器
     */
    private LinearLayoutManager layoutManager;

    /**
     * 适配器
     */
    private Adapter adapter;

    /**
     * 添加拖动处理
     */
    private ItemTouchHelper mItemTouchHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化数据
        initData();

        //1 . 从布局中获取 RecyclerView
        recycler_view = findViewById(R.id.recycler_view);

        //2 . 创建并设置布局管理器
        //创建布局管理器
        layoutManager = new LinearLayoutManager(
                this,
                RecyclerView.VERTICAL,
                false);

        //设置布局管理器
        recycler_view.setLayoutManager(layoutManager);

        // 设置边距
        recycler_view.addItemDecoration(new ItemDecoration());

        //3 . 创建并设置列表适配器
        adapter = new Adapter();
        recycler_view.setAdapter(adapter);

        //4. 添加拖动事件
        Callback callback = new Callback();
        mItemTouchHelper = new ItemTouchHelper(callback);
        //mItemTouchHelper.attachToRecyclerView(recycler_view);
    }

    /**
     * 初始化数据
     */
    private void initData(){
    
        names.add("宋江");
        names.add("卢俊义");
        names.add("吴用");
        names.add("公孙胜");
        names.add("关胜");
        names.add("林冲");
        names.add("秦明");
        names.add("呼延灼");
        names.add("花荣");
        names.add("柴进");
        names.add("李应");
        names.add("朱仝");
        names.add("鲁智深");
        names.add("武松");
        names.add("董平");
        names.add("张清");
        names.add("杨志");
        names.add("徐宁");
        names.add("索超");
    }

    /**
     * RecyclerView 适配器
     */
    public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
    

        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
            View root_view = LayoutInflater.from(MainActivity.this)
                    .inflate(R.layout.item_recyclerview, parent, false);
            return new ViewHolder(root_view);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    
            holder.text.setText("" + names.get(position));
        }

        @Override
        public int getItemCount() {
    
            return names.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView text;
            public ViewHolder(@NonNull View itemView) {
    
                super(itemView);
                text = itemView.findViewById(R.id.text);
            }
        }
    }

}

2、ItemTouchHelper.Callback 回调类


package kim.hsl.recyclerview;

import android.graphics.Canvas;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

public class Callback extends ItemTouchHelper.Callback {
    

    @Override
    public boolean isLongPressDragEnabled() {
    
        return super.isLongPressDragEnabled();
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
    
        return super.isItemViewSwipeEnabled();
    }

    @Override
    public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
    
        super.onSelectedChanged(viewHolder, actionState);
    }

    @Override
    public void onMoved(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, int fromPos, @NonNull RecyclerView.ViewHolder target, int toPos, int x, int y) {
    
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
    }

    /**
     * 设置上下左右动作
     * 只有在此处打开了指定方向的设置 , 才可以应用具体方向的拖动
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
    
        /*
            设置拖动方向, 此处设置上下拖动事件
         */
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;

        /*
            设置滑动方向, 此处设置左右侧滑事件
         */
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

        // 应用 拖动 和 滑动 设置
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
    
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    

    }

    @Override
    public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
    
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    @Override
    public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
    
        super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }
}





四、博客资源



博客资源 :

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/han1202012/article/details/118580739

智能推荐

黑马CSS笔记(四)移动端开发_jiujiujm的博客-程序员秘密

移动WEB开发之流式布局01 移动端基础1.1 浏览器现状1.2 手机屏幕现状02 视口视口就是屏幕区域。2.1 布局视口layout viewport2.2 视觉视口visual viewport2.3 理想视口 ideal viewport2.5 meta视口标签2.6 标准的viewport设置 &lt;meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-

hiberante memcached_qiuyabing的博客-程序员秘密

先了解一下什么是memcachedMemcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。Memcached 的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。memcached的使用一 Memc...

ZigBee与WiFi的双模无线网关设计方案解析_千样的博客-程序员秘密

http://www.elecfans.com/tongxin/119/20140930355368.html

Android 在动画结束回调onAnimationEnd()中remove view的崩溃解决方法及源码分析_onanimationend移除view会crash_薛瑄的博客-程序员秘密

问题:问题描述起来很简单,就是在动画结束的时候,调用父view删除子view,出现崩溃,信息如下:java.lang.NullPointerExceptionAttempt to read from field 'int android.view.View.mViewFlags' on a null object reference android.view.ViewGroup.dispa...

navicat通过ssh方式连接阿里云服务器mysql_NEO_L的博客-程序员秘密

第一步:首先配置阿里云安全组,开放3306端口(上网搜即可)第二步:通过配置navicat连接方式(1)配置ssh       (2)配置mssql连接(3)这两个配置完之后,点击连接测试即可...

随便推点

Qml动画过渡-Transition_qml transition_tony_xj的博客-程序员秘密

Qml可以使用状态来驱动界面,但这种变化是“突变”的,从用户角度来说是不友好的,需要使用Transition(过渡)来使状态的变化比较平滑。Transition的属性from/to:指定过渡的起始和结束状态。默认值是“*”,可以匹配所有状态。animations:动画列表,默认在Transition添加动画的执行顺序是并行的,target属性无需指定(因为State中已经指定了)。代码实例import QtQuick 2.0Rectangle{ id:rootItem

CSDN高校俱乐部招募公告_高校俱乐部的博客-程序员秘密

CSDN高校俱乐部欢迎你,未来的学生领袖!CSDN高校俱乐部(以下简称“俱乐部”)是非盈利性的、面向全国大学生的IT技术组织。俱乐部借力全球最大中文IT社区CSDN的丰富内容及行业资源,为在校学生提供行业资讯、技术学习、专家交流、技术竞赛、开发项目、企业人才需求等平台和资源,助力在校大学生做好职涯准备和成长。俱乐部已在全国60余所高校中建立俱乐部分站。分站俱乐部由高校在校生代表申请成立,经

遗传算法入门(Genetic Algorithm)_dadaadao的博客-程序员秘密

<br />本文为转载,由本人整理打包。<br />[说明:由于该篇文章字数多且含有不少图片,通过手工在百度博客上发布过于繁琐,费时费力且效果不理想。故在此仅列出部分文字摘要,有兴趣者可通过提供的链接下载已打包好的文章,格式为.mht。]<br /> <br />文章下载链接:http://cn.ziddu.com/download.php?uid= a62imZembq6h4palaLKWlJmiaqyclpc%3D8(验证码区分大小写)<br />文章内容转载自zzwu的博客:http://blog.c

云计算技术与应用_mrtrying.的博客-程序员秘密

#云计算与大数据技术与应用##云计算概述###1.1什么是云计算云计算的概念:现阶段对云计算的定义有多种说法。对于到底什么是云计算,至少可以找到100种解释。广为接受的说法是美国国家标准与技术研究院(NTSI)定义:云计算是一种按使用量付费的模式,这种模式提供可用的、便捷的、按需的网络访问,进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这些资源能够被快速提供,只需要投入的管理工作,或与服务供应商进行很少的交互。首先对云计算这三个字的理解,云,是网络、互联网的一种比喻说法

valgrind 工具介绍和简单的使用_weixin_30793643的博客-程序员秘密

最近老是遇上各种奇奇怪怪的core dump,不太会分析的情况下看到了这款工具。在这记录分享下。Valgrind 是个开源的工具,功能很多。例如检查内存泄漏工具---memcheck。Valgrind 安装:去官网下载: http://valgrind.org/downloads/current.html#current安装过程:(可以直接查看README文档来确认安装过程)...

python列表的内置方法_总结:11个Python3列表内置方法大全及示例_白衣卿相李梦得的博客-程序员秘密

151.jpg概述Python中的列表是简直可说是有容乃大,虽然看似类似C中的数组,但是Python列表可以接受任意的对象元素,比如,字符串,数字,布尔值,甚至列表,字典等等,自由度提升到一个新的高度,而Python也提供了大量列表相关的内置方法来有效操作列表:方法描述append将单个对象添加至列表末尾clear删除列表中所有项目copy列表的浅拷贝,参见上篇文章《Python列表赋值,复制,深...

推荐文章

热门文章

相关标签