0

Problem

So I have a recycler view populated by card views all with drag listeners attached, the motion events work fine until I set a view to be dragged, so with the line commented out this works, all logs are printed perfectly

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;
        }
    });

but if I uncomment the line

mDragStartListener.onStartDrag(holder);

then ACTION_UP is no longer called and I'm confused as to why

the listener is an interface

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

I implement it in my activity and pass it to the adapter

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

My onMove method is this

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

and in my adapter i have an onItemMove from an interface

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;
}
martinseal1987
  • 1,862
  • 8
  • 44
  • 77

1 Answers1

1

Try add below and run:

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;
        }
    });

As According to your code the flow is not right.If you return false on any Motion action before ACTION_UP then the code of ACTION_UP will not be called.

P.S: I prefer returning true from onTouch until and unless i have to take care of special cases.If there are special case return proper boolean value.

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;
        }
    });
Anmol
  • 8,110
  • 9
  • 38
  • 63
  • thank you I think i had something like this earlier but got lost while trying to fix it, but this code (both snippets) lead to the same conclusion so it works perfectly until i uncomment the line mDragStartListener.onStartDrag(holder); – martinseal1987 Sep 03 '18 at 13:56
  • 1
    mDragStartListener.onStartDrag(holder); from what i can see on Down u are just initiating a call it has no relation to motion event's.From your sample code i am sure that issue is not in the event management.Try to debug and check if there is some where infinite loop. As once ACTION_DOWN is called All other Event's are called untils its ACTION_UP/CANCLE. – Anmol Sep 03 '18 at 17:11
  • Check one more things is the MOVE action is ever terminated while debugging.As the use case you have i use it all the time in my applications.So event are for sure not the problem. – Anmol Sep 03 '18 at 17:13
  • thanks for your replies I haven't noticed any loops I have an onMove method I'll add it to the question – martinseal1987 Sep 03 '18 at 20:01