RecyclerView 与 ViewPager横向拖拽事件冲突解决(horizontal drag conflicts between ViewPager and RecyclerView)

public abstract static class DragItemTouchHelper extends ItemTouchHelper.Callback {

        private static final String TAG = "DragItemTouchHelper";

        private DragAnswerAdapter adapter;

        public DragItemTouchHelper(DragAnswerAdapter adapter) {
            this.adapter = adapter;
        }

        @Override
        public boolean isLongPressDragEnabled() {
            return false;
        }

        @Override
        public boolean isItemViewSwipeEnabled() {
            return false;
        }

        @Override
        public float getMoveThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
            return 0.8f;
        }

        @Override
        public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
            if (adapter.isPosted() || !adapter.isEnabled()) {
                return 0;
            }
            return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0);
        }

        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder from, @NonNull RecyclerView.ViewHolder to) {
            int fromPosition = from.getAdapterPosition();   //拖动的position
            int toPosition = to.getAdapterPosition();     //释放的position            return false;
            if (fromPosition % 3 == 2 && toPosition % 3 == 2) {
                return false;
            }
            if (fromPosition % 3 == 0 || toPosition % 3 == 0) {
                return false;
            }
            onDragStart(fromPosition, toPosition);
            adapter.itemMove(fromPosition, toPosition);
            adapter.notifyDataSetChanged();
            return true;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {

        }

        public abstract void onDragStart(int fromPos, int toPos);

        public abstract void onDragEnd(int fromPos, int toPos);

        @Override
        public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
            super.onSelectedChanged(viewHolder, actionState);
            Log.d(TAG, "onSelectedChanged: " + (viewHolder == null ? -1 :
                    viewHolder.getAdapterPosition()));
        }

        @Override
        public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
            super.clearView(recyclerView, viewHolder);
            Log.d(TAG, "clearView: " + viewHolder.getAdapterPosition());
            onDragEnd(viewHolder.getAdapterPosition(), -1);
        }
    }

2.开始拖拽 

 answerAdapter = new DragAnswerAdapter(data);
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
        layoutManager.setAutoMeasureEnabled(true);
        answer.setNestedScrollingEnabled(false);
        answer.setHasFixedSize(true);
        answer.setLayoutManager(layoutManager);
        answer.setAdapter(answerAdapter);
        ItemTouchHelper helper = new ItemTouchHelper(new DragAnswerAdapter.DragItemTouchHelper(answerAdapter) {

            @Override
            public void onDragStart(int fromPos, int toPos) {
                Log.d(TAG, "topic drag started: ");
                quizFragmentViewModel.setDrag(true);
            }

            @Override
            public void onDragEnd(int fromPos, int toPos) {
                Log.d(TAG, "topic drag ended: ");
                quizFragmentViewModel.setDrag(false);
            }
        });
        helper.attachToRecyclerView(answer);
        answer.addOnItemTouchListener(new OnRecyclerItemClickListener(answer) {
            @Override
            public void onItemLongClick(RecyclerView.ViewHolder vh) {
                super.onItemLongClick(vh);
                if (vh.getAdapterPosition() % 3 == 0 || !quizFragmentViewModel.getEnabled().getValue()) {
                    return;
                }
                helper.startDrag(vh);
            }

        });

3. 监控拖拽状态

 //处理嵌套拖拽问题,禁止viewpager的touch事件处理
        quizFragmentViewModel.getDrag().observe(this, aBoolean -> {
            if (aBoolean) {
                Log.d(TAG, "drag initPager: can scroll false");
                pager.setCanScroll(false);
            } else {
                Log.d(TAG, "drag initPager: can scroll true");
                pager.setCanScroll(true);
            }
        });

4. 自定义Pager,修改拖拽后的第一个OnMove Touch Event

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

public class VKViewPager extends ViewPager {

    private static final String TAG = "VKViewPager";
    private boolean canScroll;
    private boolean isDragging = false;

    public VKViewPager(@NonNull Context context) {
        super(context);
        canScroll = true;
    }

    public VKViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        canScroll = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onTouchEvent.drag: " + ev.getAction() + "\t" + ev.getX());
        return canScroll && super.onTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "drag dispatchTouchEvent: " + canScroll + "\t type" + ev.getAction() + "\t" + ev.getX() + "\t" + isDragging);
        if (isDragging && canScroll && ev.getAction() == MotionEvent.ACTION_MOVE) {
            ev.setAction(MotionEvent.ACTION_CANCEL);
            super.dispatchTouchEvent(ev);
            ev.setAction(MotionEvent.ACTION_DOWN);
            isDragging = false;
            Log.d(TAG, "dispatchTouchEvent.drag: cancel!");
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "drag onInterceptTouchEvent: " + canScroll + "\t type" + ev.getAction() + "\t" + ev.getX());
        return canScroll && super.onInterceptTouchEvent(ev);
    }

    public void setCanScroll(boolean canScroll) {
        Log.d(TAG, "drag setCanScroll: " + canScroll);
        if (!canScroll) {
            isDragging = true;
        }
        this.canScroll = canScroll;
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
        Log.d(TAG, "drag scrollTo: " + x + "\t" + y + "\t" + canScroll);
    }

}

5.done.解决横向拖拽后跳动一段距离的问题

你可能感兴趣的:(java,Android)