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.解决横向拖拽后跳动一段距离的问题