RecyclerView通过itemTouchHelper进行拖放,当拖动速度很快的时候会有些奇怪

我一直遵循这个链接的指导“拖放和RecyclerView – 通过IPaulPro刷卡” ,我有一些情况下几个问题。

所以,我基本上做了所有他解释+我在项目中添加一个TextView,表示RecyclerView中的项目的位置,如下所示: 在这里输入图像说明

除了当我开始“快速拍摄”项目时,一切都显得很好,然后我有两个问题:

  1. 它恰好有一个重复的数字。 在这里输入图像说明

    另外我所做的是在onItemClear()方法中使用onItemClear() – 它以某种方式修复了它,但是导致了IllegalStateException ,这会导致IndexOutOfBoundsexception。

  2. 偶尔,当快速滑动时,项目会进入“背景”。 这只能看到,如果物品是不一样的大小。 在这里输入图像说明

我将在下面粘贴我的整个适配器代码,在其中的某个地方肯定有缺陷。

 LayoutInflater inflater; Context context; AndroidEntityQuestionResult androidEntityQuestionResult; ArrayList<AndroidEntityAnswer> list = new ArrayList<>(); ORDLayoutManagerQuestion ord; ScreenDimensionsConstants sdc; public OrderingRecycleAdapter(Context context, AndroidEntityQuestionResult androidEntityQuestionResult, ORDLayoutManagerQuestion ord) { inflater = LayoutInflater.from(context); this.context = context; this.list = androidEntityQuestionResult.getAndroidEntityQuestion().getEntityAnswer(); this.androidEntityQuestionResult = androidEntityQuestionResult; this.ord = ord; sdc = new ScreenDimensionsConstants(context); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.custom_row_ordering_rv, parent, false); final RecyclerView.ViewHolder holder = new OrderingViewHolder(view); return holder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof OrderingViewHolder) { ((OrderingViewHolder) holder).answerText.setText(list.get(position).getAnswer().getANSWER_TEXT()); int currentPosition = position + 1; ((OrderingViewHolder) holder).position.setText("#" + currentPosition); } } @Override public int getItemCount() { return list.size(); } @Override public boolean onItemMove(int fromPosition, int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(list, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(list, i, i - 1); } } notifyItemMoved(fromPosition, toPosition); notifyItemChanged(fromPosition); return true; } @Override public void onItemDismiss(int position) { } @Override public void onStartDrag(RecyclerView.ViewHolder viewHolder) { ord.getItemTouchHelper().startDrag(viewHolder); } class OrderingViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder { private TextView answerText; private ImageView pin; private TextView position; public OrderingViewHolder(View itemView) { super(itemView); answerText = (TextView) itemView.findViewById(R.id.orderingAnswer); answerText.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40); pin = (ImageView) itemView.findViewById(R.id.ordering_pin); pin.getLayoutParams().width = sdc.getHeight() / 15; pin.getLayoutParams().height = sdc.getHeight() / 15; pin.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { OrderingRecycleAdapter.this.onStartDrag(OrderingViewHolder.this); } return false; } }); position = (TextView) itemView.findViewById(R.id.answer_position); position.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40); } @Override public void onItemSelected() { itemView.setBackgroundResource(R.drawable.menu_item_background_ice_blue); } @Override public void onItemClear() { itemView.setBackgroundResource(R.drawable.menu_item_background_white); int currentPosition = getLayoutPosition() + 1; position.setText("#" + currentPosition); //notifyDataSetChanged(); } } 

奖金问题

是否有任何教程或任何有关的信息拖放2 RecyclerViews之间?

我知道有这个问题,但没有答案,我可能在这里更幸运。

Solutions Collecting From Web of "RecyclerView通过itemTouchHelper进行拖放,当拖动速度很快的时候会有些奇怪"

改变你的onitemmove方法

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

至:

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

对我来说,似乎你的onItemMove()不考虑所有的变化。 当某物移动多于一个物品时(比如说A和B之间),你正在交换两者之间的所有物品。 但是,只向A和B报告更改,而不报告中间的其他元素。

我build议你写一个交换方法,报告所有的变化:

 public boolean swapItems(int fromPosition, int toPosition){ Collections.swap(list, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); notifyItemMoved(toPosition, fromPosition); // And maybe also notifyItemChanged() as the item changes due to the shift notifyItemChanged(fromPosition); notifyItemChanged(toPosition); } 

调用此函数而不是Collections.swap()并删除通知代码的其余部分。