RecyclerView实现相册滑动选择功能

效果如下:
效果图
这里仅说明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,来实现滑动多选的功能。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值