Sek*_*991 10 android drag-and-drop android-recyclerview
我一直在关注这个链接的指南"使用RecyclerView拖动和滑动 - 由IPaulPro",我在某些情况下遇到的问题很少.
所以,我基本上完成了他解释的所有内容+我在项目中添加了一个TextView,表示RecyclerView中项目的位置,如下所示:

一切都很好看,除非我开始"快速射击"物品,然后我有两个问题:
我所做的也是notifyAdapterSetChanged()在
onItemClear()方法中使用- 它以某种方式修复它,但导致了
IllegalStateException捕获 - 会导致
IndexOutOfBounds异常.
我将在下面粘贴我的整个适配器代码,其中必须存在缺陷.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
奖金问题
是否有任何教程或任何与2个RecyclerViews之间的拖放相关的信息?
我知道有关于SO的问题,但没有答案,我可能会更幸运.
对我来说,您的 onItemMove() 似乎并未考虑所有更改。当某物移动多个项目时(假设在 A 和 B 之间),您将在两者之间交换所有项目。但是,您仅报告 A 和 B 的更改,而不报告其间的其余元素。
我建议您编写一个报告所有更改的交换方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
调用此函数而不是 Collections.swap() 并删除其余的通知代码。
| 归档时间: |
|
| 查看次数: |
3889 次 |
| 最近记录: |