效果如下:
这里仅说明RecyclerView滑动多选,首先要获取RecyclerView滑动事件,代码如下:
public class MyRecyclerView extends RecyclerView {
private DispatchTouchEventListener dispatchTouchEventListener;
public MyRecyclerView(@NonNull Context context) {
super(context);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setDispatchTouchEventListener(DispatchTouchEventListener dispatchTouchEventListener) {
this.dispatchTouchEventListener = dispatchTouchEventListener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (dispatchTouchEventListener != null) {
dispatchTouchEventListener.action(ev);
}
return super.dispatchTouchEvent(ev);
}
public interface DispatchTouchEventListener {
void action(MotionEvent ev);
}
}
我们重写dispatchTouchEvent
方法,获取touch事件,在RecyclerView中有这样一个方法findChildViewUnder
,可以根据传入的x,y坐标,获取对应的itemView,只要我们获取到这个childView,就可以操作它了。
...
@Nullable
public View findChildViewUnder(float x, float y) {
int count = this.mChildHelper.getChildCount();
for(int i = count - 1; i >= 0; --i) {
View child = this.mChildHelper.getChildAt(i);
float translationX = child.getTranslationX();
float translationY = child.getTranslationY();
if (x >= (float)child.getLeft() + translationX && x <= (float)child.getRight() + translationX && y >= (float)child.getTop() + translationY && y <= (float)child.getBottom() + translationY) {
return child;
}
}
return null;
}
...
完整代码:
public class MainActivity extends AppCompatActivity {
private List<Boolean> datas = new ArrayList<>();
private int downX;
private int downY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 100; i++) {
datas.add(false);
}
final MyRecyclerView mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
mRecyclerView.setAdapter(new RecyclerView.Adapter() {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new ViewHolder(LayoutInflater.from(MainActivity.this).inflate(R.layout.item_img, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
if (viewHolder instanceof ViewHolder) {
((ViewHolder) viewHolder).bindViewHolder(i, datas.get(i));
}
}
@Override
public int getItemCount() {
return datas.size();
}
});
mRecyclerView.setDispatchTouchEventListener(new MyRecyclerView.DispatchTouchEventListener() {
int lastPostion = -1;
@Override
public void action(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getX();
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) ev.getX();
int moveY = (int) ev.getY();
if (Math.abs(moveX - downX) > Math.abs(moveY - downY)) {
//左右滑动
View childViewUnder = mRecyclerView.findChildViewUnder(moveX, moveY);
if (childViewUnder != null) {
int tag = (Integer) childViewUnder.getTag();
if (lastPostion == tag) {
return;
}
RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForLayoutPosition(tag);
if (viewHolder instanceof ViewHolder) {
((ViewHolder) viewHolder).setSelect();
}
lastPostion = tag;
}
}
break;
case MotionEvent.ACTION_UP:
lastPostion = -1;
break;
default:
break;
}
}
});
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView selectImg;
ViewHolder(@NonNull View itemView) {
super(itemView);
selectImg = itemView.findViewById(R.id.item_select_img);
}
void bindViewHolder(int position, boolean isSelect) {
itemView.setTag(position);
if (isSelect) {
selectImg.setImageResource(R.drawable.ck_imagepicker_grid_selected);
} else {
selectImg.setImageResource(R.drawable.ck_imagepicker_grid_normal);
}
}
void setSelect() {
int position = (int) itemView.getTag();
datas.set(position, true);
selectImg.setImageResource(R.drawable.ck_imagepicker_grid_selected);
}
}
}
布局文件就一个RecyclerView,就不贴出来了,原理很简单,在bindViewHolder中给itemView设置tag,监听RecyclerView的touch事件,获取对应的x,y坐标,根据x,y坐标获取RecyclerView中的childView,来实现滑动多选的功能。