//一.第一种方式 通过BaseItemDraggableAdapter类和其提供的的拖拽监听实现:
//1.第一步 导入依赖库和权限:
//依赖库:
//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'
//RecyclerAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28'
//用到的权限:
<!--振动-->
<uses-permission android:name="android.permission.VIBRATE" />
//2.第二步 新建ItemDraggableActivity页面:
//manifest注册:
<activity
android:name=".phone.activity.ItemDraggableActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
tools:ignore="LockedOrientationActivity" />
//activity代码:
/**
* @author CJF
*/
public class ItemDraggableActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemChildClickListener, View.OnClickListener {
private final GridLayoutManager manager = new GridLayoutManager(this, 3);
private final ItemDraggableAdapter adapter = new ItemDraggableAdapter(R.layout.item_draggable_item, new ArrayList<>());
/**
* 震动时长(毫秒)
*/
private final int milliseconds = 50;
private Vibrator vibrator;
private RecyclerView mTreeListRecy;
private TextView mEdit;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tree_list);
//点击音效
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mTreeListRecy = findViewById(R.id.mTreeListRecy);
mEdit = findViewById(R.id.mEdit);
mEdit.setOnClickListener(this);
mTreeListRecy.setLayoutManager(manager);
mTreeListRecy.setAdapter(adapter);
DragAndSwipeCallback itemDragAndSwipeCallback = new DragAndSwipeCallback(adapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
itemTouchHelper.attachToRecyclerView(mTreeListRecy);
//可以不用设置,可以拖拽的方向,默认上下左右
itemDragAndSwipeCallback.setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
// 开启拖拽 设置可拖拽item的根布局id
adapter.enableDragItem(itemTouchHelper, R.id.mItemDraggableItemLin, true);
adapter.setOnItemDragListener(onItemDragListener);
// 开启滑动删除
// adapter.enableSwipeItem();
// adapter.setOnItemSwipeListener(onItemSwipeListener);
adapter.setOnItemChildClickListener(this);
List<ItemDraggableBean> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ItemDraggableBean bean = new ItemDraggableBean();
bean.setName("数据" + i);
list.add(bean);
}
adapter.addData(list);
}
/**
* 拖拽监听
*/
private OnItemDragListener onItemDragListener = new OnItemDragListener() {
@Override
public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
Log.e("TAG1231", "onItemDragStart" + "你在拖拽第" + (pos + 1) + "个位置的item哦!");
//震动
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(milliseconds);
}
//按住变大
viewHolder.itemView.setScaleX(1.2f);
viewHolder.itemView.setScaleY(1.2f);
viewHolder.itemView.setAlpha(0.5f);
//改变数据状态
ItemDraggableBean draggableBean = adapter.getData().get(pos);
if (!draggableBean.isShow()) {
List<ItemDraggableBean> data = adapter.getData();
for (ItemDraggableBean bean : data) {
bean.setShow(true);
}
//循环遍历出所有的item布局 并显示图片
//注意不可以直接使用 adapter.notifyDataSetChanged();数据刷新会导致直接调用onItemDragEnd()方法
for (int i = 0; i < mTreeListRecy.getChildCount(); i++) {
View childAt = mTreeListRecy.getChildAt(i);
TextView textView = childAt.findViewById(R.id.mItemDraggableItemText);
View view = childAt.findViewById(R.id.mItemDraggableItemImg);
view.setVisibility(View.VISIBLE);
Log.e("TAG1231", "textView:" + textView.getText().toString());
}
mEdit.setText("完成");
}
}
@Override
public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
Log.e("TAG1231", "onItemDragMoving");
}
@Override
public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
Log.e("TAG1231", "onItemDragEnd" + "拖拽到了第" + (pos + 1) + "个位置哦!");
//变回原来大小
viewHolder.itemView.setScaleX(1.0f);
viewHolder.itemView.setScaleY(1.0f);
viewHolder.itemView.setAlpha(1.0f);
}
};
OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() {
@Override
public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {
ToastUtil.getInstance().showToast("继续向左滑动即可删除第" + (pos + 1) + "个位置的item");
}
@Override
public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {
}
@Override
public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
ToastUtil.getInstance().showToast("删除了第" + (pos + 1) + "个位置的item哦");
}
@Override
public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {
}
};
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
adapter.remove(position);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.mEdit:
boolean isEdit = "编辑".equals(mEdit.getText().toString());
List<ItemDraggableBean> data = adapter.getData();
for (ItemDraggableBean bean : data) {
bean.setShow(isEdit);
}
adapter.notifyDataSetChanged();
mEdit.setText(isEdit ? "完成" : "编辑");
break;
default:
break;
}
}
}
//3.第三步 新建DragAndSwipeCallback类继承ItemDragAndSwipeCallback,重写onChildDraw 防止越界拖动:
/**
* @author CJF
* 重写onChildDraw 防止越界拖动
*/
public class DragAndSwipeCallback extends ItemDragAndSwipeCallback {
public DragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
super(adapter);
}
/**
* 重写onChildDraw 防止越界拖动
*
* @param c
* @param recyclerView
* @param viewHolder
* @param dX
* @param dY
* @param actionState
* @param isCurrentlyActive
*/
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
float topY = viewHolder.itemView.getTop() + dY;
float bottomY = topY + viewHolder.itemView.getHeight();
float leftX = viewHolder.itemView.getLeft() + dX;
float rightX = leftX + viewHolder.itemView.getWidth();
if (topY < 0) {
dY = 0;
} else if (bottomY > recyclerView.getHeight()) {
dY = recyclerView.getHeight() - viewHolder.itemView.getHeight() - viewHolder.itemView.getTop();
}
if (leftX < 0) {
dX = viewHolder.itemView.getWidth() - viewHolder.itemView.getRight();
} else if (rightX > recyclerView.getWidth()) {
dX = recyclerView.getWidth() - viewHolder.itemView.getWidth() - viewHolder.itemView.getLeft();
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
//4.第四步 新建ItemDraggableAdapter适配器类:
/**
* @author CJF
*/
public class ItemDraggableAdapter extends BaseItemDraggableAdapter<ItemDraggableBean, BaseViewHolder> {
public ItemDraggableAdapter(List<ItemDraggableBean> data) {
super(data);
}
public ItemDraggableAdapter(int layoutResId, List<ItemDraggableBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, ItemDraggableBean item) {
helper.setText(R.id.mItemDraggableItemText, item.getName());
helper.setGone(R.id.mItemDraggableItemImg, item.isShow());
helper.addOnClickListener(R.id.mItemDraggableItemImg);
}
}
//5.第五步 新建ItemDraggableBean类:
/**
* @author CJF
*/
public class ItemDraggableBean {
private String name;
private boolean isShow = false;
public ItemDraggableBean() {
}
public ItemDraggableBean(String name, boolean isShow) {
this.name = name;
this.isShow = isShow;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isShow() {
return isShow;
}
public void setShow(boolean show) {
isShow = show;
}
}
//6.第六步 各个xml布局文件以及svg图片文件:
//activity_tree_list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/color_white"
android:orientation="vertical">
<TextView
android:id="@+id/mEdit"
android:background="@drawable/selector_common_item"
android:textColor="@color/colorAccent"
android:textStyle="bold"
android:textSize="18sp"
android:gravity="center"
android:text="编辑"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/mTreeListRecy"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
//item_draggable_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_search"
android:layout_margin="@dimen/dp_5"
android:id="@+id/mItemDraggableItemLin"
android:orientation="horizontal">
<TextView
android:id="@+id/mItemDraggableItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left|center_vertical"
android:minHeight="@dimen/dp_50"
android:padding="@dimen/dp_10"
android:text="text"
android:textColor="@color/black"
android:textSize="@dimen/sp_15" />
<ImageView
android:scaleType="center"
android:id="@+id/mItemDraggableItemImg"
android:src="@drawable/crm_close"
android:layout_width="@dimen/dp_50"
android:layout_height="match_parent"/>
</LinearLayout>
//svg图片文件 crm_close:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
//二.第二种方式 通过继承ItemTouchHelper.Callback类重写几个方法实现:
//1.第一步 导入依赖库:
//RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'
//RecyclerAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28'
//2.第二步 新建ItemDraggableActivity页面:
//manifest注册:
<activity
android:name=".phone.activity.ItemDraggableActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
tools:ignore="LockedOrientationActivity" />
//activity代码:
/**
* @author CJF
*/
public class ItemDraggableActivity extends AppCompatActivity implements BaseQuickAdapter.OnItemChildClickListener, BaseQuickAdapter.OnItemLongClickListener {
private final GridLayoutManager manager = new GridLayoutManager(this, 3);
private final ItemDraggableAdapter adapter = new ItemDraggableAdapter(R.layout.item_draggable_item);
private RecyclerView mTreeListRecy;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tree_list);
mTreeListRecy = findViewById(R.id.mTreeListRecy);
mTreeListRecy.setLayoutManager(manager);
mTreeListRecy.setAdapter(adapter);
adapter.setOnItemChildClickListener(this);
adapter.setOnItemLongClickListener(this);
//列表上下左右拖拽滑动
AdapterTouchHelper adapterTouchHelper = new AdapterTouchHelper(mTreeListRecy, adapter);
List<ItemDraggableBean> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ItemDraggableBean bean = new ItemDraggableBean();
bean.setName("数据" + i);
list.add(bean);
}
adapter.addData(list);
}
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
adapter.remove(position);
}
@Override
public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
//改变数据状态
ItemDraggableBean draggableBean = (ItemDraggableBean) adapter.getData().get(position);
if (!draggableBean.isShow()) {
List<ItemDraggableBean> data = adapter.getData();
for (ItemDraggableBean bean : data) {
bean.setShow(true);
}
//循环遍历出所有的item布局 并显示图片
//注意不可以直接使用 adapter.notifyDataSetChanged();数据刷新会导致直接结束滑动
for (int i = 0; i < mTreeListRecy.getChildCount(); i++) {
View childAt = mTreeListRecy.getChildAt(i);
TextView textView = childAt.findViewById(R.id.mItemDraggableItemText);
View mItemDraggableItemImg = childAt.findViewById(R.id.mItemDraggableItemImg);
mItemDraggableItemImg.setVisibility(View.VISIBLE);
Log.e("TAG1231", "textView:" + textView.getText().toString());
}
}
return false;
}
}
//3.第三步 新建ItemDraggableAdapter适配器:
/**
* @author CJF
*/
public class ItemDraggableAdapter extends BaseQuickAdapter<ItemDraggableBean, BaseViewHolder> {
public ItemDraggableAdapter(int layoutResId) {
super(layoutResId);
}
@Override
protected void convert(BaseViewHolder helper, ItemDraggableBean item) {
helper.setText(R.id.mItemDraggableItemText, item.getName());
helper.setGone(R.id.mItemDraggableItemImg, item.isShow());
helper.addOnClickListener(R.id.mItemDraggableItemImg);
}
}
//4.第四步 新建AdapterTouchHelper类继承ItemTouchHelper.Callback实现核心功能:
/**
* @author CJF
* 列表上下左右拖拽滑动
*/
public class AdapterTouchHelper extends ItemTouchHelper.Callback {
private BaseQuickAdapter adapter;
public AdapterTouchHelper(RecyclerView recyclerView, BaseQuickAdapter adapter) {
this.adapter = adapter;
//用Callback构造ItemtouchHelper
ItemTouchHelper touchHelper = new ItemTouchHelper(this);
//调用ItemTouchHelper的attachToRecyclerView方法建立联系
touchHelper.attachToRecyclerView(recyclerView);
}
@Override
public int getMovementFlags(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder) {
//允许上下拖动
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, 0);
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
/**
* Item进行上下移动从旧的位置到新的位置的时候会调用该方法
*
* @param recyclerView
* @param viewHolder 旧位置
* @param target 目标位置
* @return
*/
@Override
public boolean onMove(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder, @NotNull RecyclerView.ViewHolder target) {
//交换位置
Collections.swap(adapter.getData(), viewHolder.getAdapterPosition(), target.getAdapterPosition());
adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
/**
* Item左右移动达到条件时时,会调用该方法
*
* @param viewHolder
* @param direction
*/
@Override
public void onSwiped(@NotNull RecyclerView.ViewHolder viewHolder, int direction) {
}
/**
* 重写onChildDraw 防止越界拖动
*
* @param c
* @param recyclerView
* @param viewHolder
* @param dX
* @param dY
* @param actionState
* @param isCurrentlyActive
*/
@Override
public void onChildDraw(@NotNull Canvas c, @NotNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
float topY = viewHolder.itemView.getTop() + dY;
float bottomY = topY + viewHolder.itemView.getHeight();
float leftX = viewHolder.itemView.getLeft() + dX;
float rightX = leftX + viewHolder.itemView.getWidth();
if (topY < 0) {
dY = 0;
} else if (bottomY > recyclerView.getHeight()) {
dY = recyclerView.getHeight() - viewHolder.itemView.getHeight() - viewHolder.itemView.getTop();
}
if (leftX < 0) {
dX = viewHolder.itemView.getWidth() - viewHolder.itemView.getRight();
} else if (rightX > recyclerView.getWidth()) {
dX = recyclerView.getWidth() - viewHolder.itemView.getWidth() - viewHolder.itemView.getLeft();
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
//开始按住滑动
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
//按住变大
viewHolder.itemView.setScaleX(1.2f);
viewHolder.itemView.setScaleY(1.2f);
viewHolder.itemView.setAlpha(0.5f);
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(@NotNull RecyclerView recyclerView, @NotNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
//结束按住滑动 变回原来大小
viewHolder.itemView.setScaleX(1.0f);
viewHolder.itemView.setScaleY(1.0f);
viewHolder.itemView.setAlpha(1.0f);
}
}
//5.第五步 新建ItemDraggableBean类:
/**
* @author CJF
*/
public class ItemDraggableBean {
private String name;
private boolean isShow = false;
public ItemDraggableBean() {
}
public ItemDraggableBean(String name, boolean isShow) {
this.name = name;
this.isShow = isShow;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isShow() {
return isShow;
}
public void setShow(boolean show) {
isShow = show;
}
}
//6.第六步 各个xml布局以及svg图片:
//activity_tree_list:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/color_white"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/mTreeListRecy"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
//item_draggable_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_search"
android:layout_margin="@dimen/dp_5"
android:id="@+id/mItemDraggableItemLin"
android:orientation="horizontal">
<TextView
android:id="@+id/mItemDraggableItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left|center_vertical"
android:minHeight="@dimen/dp_50"
android:padding="@dimen/dp_10"
android:text="text"
android:textColor="@color/black"
android:textSize="@dimen/sp_15" />
<ImageView
android:scaleType="center"
android:id="@+id/mItemDraggableItemImg"
android:src="@drawable/crm_close"
android:layout_width="@dimen/dp_50"
android:layout_height="match_parent"/>
</LinearLayout>
//svg图片 crm_close:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
//------------------------------------------------------END---------------------------------------------------------------