本章节讲述RecyclerView左滑删除功能。
https://blog.csdn.net/weixin_37730482/article/details/72866943
这篇文章有讲解RecyclerView有一个ItemTouchHelper工具类,该工具类有一个叫CallBack的内部静态类。其实也可实现左滑删除,但是onChildDraw方法中不好处理删除时的布局。所以本章节讲述自定义RecyclerView的方式实现左滑删除。
1.自定义View
package com.wjn.viewlistdemo.activity.recyclerview.del;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;
import com.wjn.viewlistdemo.R;
public class DelRecyclerView extends RecyclerView {
private static final String TAG = "DelRecyclerView";
private int maxLength, mTouchSlop;
private int xDown, yDown, xMove, yMove;
private int curSelectPosition;//当前选中的item位置
private LinearLayout mCurItemLayout;//当前选中的item布局
private RelativeLayout mLlHidden;//隐藏部分
private LinearLayout mLastItemLayout;
private int mHiddenWidth;//隐藏部分长度
private int mMoveWidth = 0;//记录连续移动的长度
private boolean isFirst = true;//是否是第一次touch
private Scroller mScroller;
/**
* 删除的监听事件
*/
private OnRightClickListener mRightListener;
public void setRightClickListener(OnRightClickListener listener) {
this.mRightListener = listener;
}
/**
* 构造方法
*/
public DelRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
/**
* 构造方法
*/
public DelRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
/**
* 初始化
*/
private void init(Context context) {
//滑动到最小距离
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
//滑动的最大距离
maxLength = ((int) (180 * context.getResources().getDisplayMetrics().density + 0.5f));
//初始化Scroller
mScroller = new Scroller(context, new LinearInterpolator(context, null));
}
/**
* onTouchEvent方法
*/
@Override
public boolean onTouchEvent(MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
//记录当前按下的坐标
xDown = x;
yDown = y;
//计算选中哪个Item
int firstPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
Rect itemRect = new Rect();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
child.getHitRect(itemRect);
if (itemRect.contains(x, y)) {
curSelectPosition = firstPosition + i;
break;
}
}
}
if (isFirst) {//第一次时,不用重置上一次的Item
isFirst = false;
} else {
//屏幕再次接收到点击时,恢复上一次Item的状态
if (mLastItemLayout != null && mMoveWidth > 0) {
//将Item右移,恢复原位
scrollRight(mLastItemLayout, (0 - mMoveWidth));
//清空变量
mHiddenWidth = 0;
mMoveWidth = 0;
}
}
//取到当前选中的Item,赋给mCurItemLayout,以便对其进行左移
View item = getChildAt(curSelectPosition - firstPosition);
if (item != null) {
//获取当前选中的Item
DelAdapter.ViewHolder viewHolder = (DelAdapter.ViewHolder) getChildViewHolder(item);
mCurItemLayout = viewHolder.layout;
//找到具体元素(这与实际业务相关了~~)
mLlHidden = mCurItemLayout.findViewById(R.id.recycleview_item_dellayout);
mLlHidden.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mRightListener != null) {
//删除
mRightListener.onRightClick(curSelectPosition, "");
}
}
});
//这里将删除按钮的宽度设为可以移动的距离
mHiddenWidth = mLlHidden.getWidth();
}
break;
case MotionEvent.ACTION_MOVE:
xMove = x;
yMove = y;
int dx = xMove - xDown;//为负时:手指向左滑动;为正时:手指向右滑动。这与Android的屏幕坐标定义有关
int dy = yMove - yDown;//
//左滑
if (dx < 0 && Math.abs(dx) > mTouchSlop && Math.abs(dy) < mTouchSlop) {
int newScrollX = Math.abs(dx);
if (mMoveWidth >= mHiddenWidth) {//超过了,不能再移动了
newScrollX = 0;
} else if (mMoveWidth + newScrollX > mHiddenWidth) {//这次要超了,
newScrollX = mHiddenWidth - mMoveWidth;
}
//左滑,每次滑动手指移动的距离
scrollLeft(mCurItemLayout, newScrollX);
//对移动的距离叠加
mMoveWidth = mMoveWidth + newScrollX;
} else if (dx > 0) {//右滑
//执行右滑,这里没有做跟随,瞬间恢复
scrollRight(mCurItemLayout, 0 - mMoveWidth);
mMoveWidth = 0;
}
break;
case MotionEvent.ACTION_UP://手抬起时
int scrollX = mCurItemLayout.getScrollX();
if (mHiddenWidth > mMoveWidth) {
int toX = (mHiddenWidth - mMoveWidth);
if (scrollX > mHiddenWidth / 2) {//超过一半长度时松开,则自动滑到左侧
scrollLeft(mCurItemLayout, toX);
mMoveWidth = mHiddenWidth;
} else {//不到一半时松开,则恢复原状
scrollRight(mCurItemLayout, 0 - mMoveWidth);
mMoveWidth = 0;
}
}
mLastItemLayout = mCurItemLayout;
break;
}
return super.onTouchEvent(e);
}
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
mCurItemLayout.scrollBy(mScroller.getCurrX(), 0);
invalidate();
Log.d(TAG, "computeScroll getCurrX ->" + mScroller.getCurrX());
}
}
/**
* 向左滑动
*/
private void scrollLeft(View item, int scorllX) {
item.scrollBy(scorllX, 0);
Log.d(TAG, " scroll left -> " + scorllX);
}
/**
* 向右滑动
*/
private void scrollRight(View item, int scorllX) {
item.scrollBy(scorllX, 0);
Log.d(TAG, " scroll right -> " + scorllX);
}
}
2.Adapter
package com.wjn.viewlistdemo.activity.recyclerview.del;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import com.wjn.viewlistdemo.activity.recyclerview.slide.SlideAdapter;
import java.util.List;
public class DelAdapter extends RecyclerView.Adapter<DelAdapter.ViewHolder> {
private List<Student> list;
private LayoutInflater mInflater;
public DelAdapter(Context context, List<Student> list) {
this.list = list;
mInflater = LayoutInflater.from(context);
}
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = mInflater.inflate(R.layout.recyclerview_item, viewGroup, false);
DelAdapter.ViewHolder holder = new DelAdapter.ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
viewHolder.textView1.setText(list.get(i).getName() + "【" + (i + 1) + "】");
viewHolder.textView2.setText(list.get(i).getDescribe());
viewHolder.circleImageView.setBackgroundResource(R.mipmap.patient_ava);
}
@Override
public int getItemCount() {
return list.size();
}
/**
* ViewHolder类
*/
class ViewHolder extends RecyclerView.ViewHolder {
public LinearLayout layout;
private ImageView circleImageView;
private TextView textView1;
private TextView textView2;
public ViewHolder(View itemView) {
super(itemView);
layout = itemView.findViewById(R.id.recycleview_item_layout);
circleImageView = itemView.findViewById(R.id.recycleview_circleimageview);
textView1 = itemView.findViewById(R.id.recycleview_item_textview1);
textView2 = itemView.findViewById(R.id.recycleview_item_textview2);
}
}
/**
* 删除数据
*/
public void removeData(int position) {
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, list.size());
}
}
3.接口
package com.wjn.viewlistdemo.activity.recyclerview.del;
public interface OnRightClickListener {
void onRightClick(int position, String id);
}
4.使用
package com.wjn.viewlistdemo.activity.recyclerview.del;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.RecyclerViewUtils;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import com.wjn.viewlistdemo.activity.recyclerview.slide.SlideAdapter;
import java.util.List;
public class DelRecyclerViewActivity extends AppCompatActivity {
private DelRecyclerView recyclerView;
private List<Student> list;
private DelAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_del_recycler_view);
initView();
}
/**
* 初始化各种View
*/
private void initView() {
recyclerView = findViewById(R.id.activity_del_recycler_view_recyclerview);
list = RecyclerViewUtils.getInstance().getList();
//1.设置LinearLayoutManager ListView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//2.设置固定大小
recyclerView.setHasFixedSize(true);
//3.设置Adapter
adapter = new DelAdapter(this, list);
recyclerView.setAdapter(adapter);
//4.左滑删除
initRightView(recyclerView);
}
private void initRightView(DelRecyclerView recyclerView) {
if (null == recyclerView) {
return;
}
recyclerView.setRightClickListener(new OnRightClickListener() {
@Override
public void onRightClick(int position, String id) {
if (null != adapter) {
adapter.removeData(position);
}
}
});
}
}