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 事件分发】ItemTouchHandler 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )
文章目录
一、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);
}
}
四、博客资源
博客资源 :
- GitHub 地址 : https://github.com/han1202012/001_RecyclerView