首页 > 解决方案 > 没有通过拖动监听器触发的 android 运动事件

问题描述

问题

所以我有一个由卡片视图填充的回收器视图,所有这些视图都附加了拖动侦听器,运动事件工作正常,直到我设置要拖动的视图,所以注释掉这行的行,所有日志都完美打印

holder.handleView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (MotionEventCompat.getActionMasked(event)){
                case MotionEvent.ACTION_DOWN:
                    Log.d("Adptr" , "ACTION_DOWN");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation_pressed));
                    //mDragStartListener.onStartDrag(holder);
                    return true;
                case MotionEvent.ACTION_UP:
                    Log.d("Adptr" , "ACTION_UP");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d("Adptr" , "ACTION_CANCEL");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
            }
            return false;
        }
    });

但是如果我取消注释该行

mDragStartListener.onStartDrag(holder);

然后 ACTION_UP 不再被调用,我很困惑为什么

监听器是一个接口

public interface OnStartDragListener {
    void onStartDrag(RecyclerView.ViewHolder viewHolder);
}

我在我的活动中实现它并将它传递给适配器

@Override
    public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
        mItemTouchHelper.startDrag(viewHolder);
    }

我的 onMove 方法是这样的

 @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                      RecyclerView.ViewHolder target) {
    mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
    return true;
}

在我的适配器中,我有一个来自接口的 onItemMove

public interface ItemTouchHelperAdapter {
  boolean onItemMove(int fromPosition, int toPosition);
  void onItemDismiss(int position);
}


@Override
  public boolean onItemMove(int fromPosition, int toPosition) {
    if (fromPosition < toPosition){
        for (int i = fromPosition; i < toPosition; i++){
            Collections.swap(cardMakerList,i,i+1);
        }
    }else{
        for (int i = fromPosition; i > toPosition; i--){
            Collections.swap(cardMakerList,i,i-1);
        }
    }
    notifyItemMoved(fromPosition,toPosition);
    return true;
}

标签: androidadapterdragmotionevent

解决方案


尝试在下面添加并运行:

holder.handleView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (MotionEventCompat.getActionMasked(event)){
                case MotionEvent.ACTION_DOWN:
                    Log.d("Adptr" , "ACTION_DOWN");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation_pressed));
                    //mDragStartListener.onStartDrag(holder);
                    return true;
                case MotionEvent.ACTION_MOVE:
                        Log.d("Adptr" , "ACTION_MOVE");
                        return true;
                case MotionEvent.ACTION_UP:
                    Log.d("Adptr" , "ACTION_UP");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d("Adptr" , "ACTION_CANCEL");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
            }
            return false;
        }
    });

由于根据您的代码,流程不正确。如果您在 ACTION_UP 之前对任何 Motion 动作返回 false,则不会调用 ACTION_UP 的代码。

PS:我更喜欢从 onTouch 返回 true,除非我必须处理特殊情况。如果有特殊情况,请返回正确的布尔值。

holder.handleView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (MotionEventCompat.getActionMasked(event)){
                case MotionEvent.ACTION_DOWN:
                    Log.d("Adptr" , "ACTION_DOWN");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation_pressed));
                    //mDragStartListener.onStartDrag(holder);
                    return true;
                case MotionEvent.ACTION_UP:
                    Log.d("Adptr" , "ACTION_UP");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d("Adptr" , "ACTION_CANCEL");
                    holder.cardView.setCardElevation(context.getResources().getDimensionPixelSize(R.dimen.elevation));
                    break;
            }
            return true;
        }
    });

推荐阅读