DingMouRen / LayoutManagerGroup

:point_right: Customize the LayoutManager of RecyclerView(自定义LayoutManager)
4.98k stars 680 forks source link

关于 SlideLayoutManager 中 item 点击事件无效 #29

Open daiwenbo88 opened 6 years ago

daiwenbo88 commented 6 years ago

因为 SlideLayoutManager 中 item 设置了setOnTouchListener()导致在adapter 中item 中其他点击事件不能处理 这个有什么思路去解决吗

private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(v);
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mItemTouchHelper.startSwipe(childViewHolder);
            }
            return false;
        }
    };
DingMouRen commented 6 years ago

@daiwenbo88 可以声明接口,将item的setOnTouchListener中的点击事件,通过接口暴露出去

daiwenbo88 commented 6 years ago

@DingMouRen 该方案已经尝试过了 是不行的 经过不断摸索 只能在 ItemTouchHelperCallback#onChildDraw()着手 且已成功 但是还有最后一点问题 就是会回调多次 (希望可以帮助到更多的人)

    private long startTime;
    private boolean isStart = true;
    private int mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

        if (isCurrentlyActive && isStart) {
            isStart = false;
            startTime = System.currentTimeMillis();
        }
        View itemView = viewHolder.itemView;
        if (!isCurrentlyActive && dX == 0 && dY == 0) {
            long endTime = System.currentTimeMillis();
            if (endTime - startTime < mClickTimeout) {
                isStart = true;
                OnAdapterItemClickListener onAdapterItemClickListener = getOnAdapterItemClickListener();
                if (null != onAdapterItemClickListener) {
                    onAdapterItemClickListener.onItemClick();
                }
            }
        }
   /////////////////////下面的代码不动////////////////////////////////
arronvera commented 5 years ago

@DingMouRen 该方案已经尝试过了 是不行的 经过不断摸索 只能在 ItemTouchHelperCallback#onChildDraw()着手 且已成功 但是还有最后一点问题 就是会回调多次 (希望可以帮助到更多的人)

    private long startTime;
    private boolean isStart = true;
    private int mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

        if (isCurrentlyActive && isStart) {
            isStart = false;
            startTime = System.currentTimeMillis();
        }
        View itemView = viewHolder.itemView;
        if (!isCurrentlyActive && dX == 0 && dY == 0) {
            long endTime = System.currentTimeMillis();
            if (endTime - startTime < mClickTimeout) {
                isStart = true;
                OnAdapterItemClickListener onAdapterItemClickListener = getOnAdapterItemClickListener();
                if (null != onAdapterItemClickListener) {
                    onAdapterItemClickListener.onItemClick();
                }
            }
        }
   /////////////////////下面的代码不动////////////////////////////////

您好,急求怎么解决,回调多次

arronvera commented 5 years ago

我出现了部分手机点击无效果,部分手机有效果

VincentJin-91 commented 5 years ago

private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {

    public boolean swiping;
    public float startx;
    public float startY;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(v);
        switch (MotionEventCompat.getActionMasked(event)) {
            case MotionEvent.ACTION_DOWN:
                startx = event.getRawX();
                startY = event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                float dx = event.getRawX() - startx;
                float dy = event.getRawY() - startY;
                double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
                if (distance > viewConfiguration.getScaledTouchSlop() && !swiping) {
                    swiping = true;
                    mItemTouchHelper.startSwipe(childViewHolder);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                swiping = false;
                break;
        }

        return false;
    }
};

他只在down里面直接startswipe,你判断已经发生滑动时在出发swipe我觉得就没啥问题了吧。。。不妨拿去试一下