由于 recyclerview 的拖放移动,如何更新 ArrayList 中的所有项目
How to update all the items in ArrayList due to shift in drag and drop of recyclerview
我有一个 RecyclerView
,其布局是 GridLayout
3 列。我正在使用 ItemTouchHelper 拖放 RecyclerView
的 GridLayout
。在我的适配器中有一个方法 onItemMove()
通知我我已经移动的项目。它只交换我拖放的 ArrayList
中的那些项目。但是由于拖放,其他元素也发生了变化。我也想更新他们在 ArrayList
.
中的位置
这是我的 Recyclerview 的适配器:
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> implements com.sagar.quizdemo.helper.ItemTouchHelperAdapter {
String[] str = {"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"};
List<String> itemList, actualList;
LayoutInflater inflater;
Context context;
private final OnStartDragListener mDragStartListener;
public GridAdapter(Context context, OnStartDragListener dragStartListener) {
this.context = context;
mDragStartListener = dragStartListener;
inflater = LayoutInflater.from(context);
itemList = new ArrayList<>();
actualList = new ArrayList<>(Arrays.asList(str));
}
public void getItemList(List<String> nameList) {
int currentSize = itemList.size();
itemList.clear();
itemList.addAll(nameList);
notifyItemRangeRemoved(0, currentSize);
notifyItemRangeInserted(0, nameList.size());
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_level_row, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.textView.setText(itemList.get(position));
// Start a drag whenever the handle view it touched
holder.cardView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
}
return false;
}
});
}
@Override
public int getItemCount() {
return itemList.size();
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(itemList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
return true;
}
@Override
public void onItemDismiss(int position) {
itemList.remove(position);
notifyItemRemoved(position);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
CardView cardView;
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.gameCard);
textView = (TextView) itemView.findViewById(R.id.gameText);
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(Color.WHITE);
}
}
}
如果列表最初是:
{"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"}
在我交换 RecyclerView 中的第二个和第四个定位元素之后。更新后的列表应该如下所示(我想要的):
{"Level 1", "Level 5", "Level 2", "Level 3", "Level 4", "Level 6", "Level 7", "Level 8", "Level 9"}
但我收到了这个更新列表:
{"Level 1", "Level 5", "Level 3", "Level 4", "Level 2", "Level 6", "Level 7", "Level 8", "Level 9"}
尝试在 onItemMove 方法中调用 notifyDataSetChanged()。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
notifyDataSetChanged();
return true;
}
我认为您的问题在于您使用 Collections.swap(itemList, fromPosition, toPosition);
,它在指定位置交换对象。所以输出是正确的。不过,您需要的是:
String item = itemList.remove(fromPostion);
itemList.insert(item, toPosition);
试试这个。在您的情况下,您首先必须找到要替换的项目的索引 (fromPosition),然后将 toPosition 添加到该索引。
How to move specific item in array list to the first item
代码 here 为我工作。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(listData, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(listData, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
我有一个 RecyclerView
,其布局是 GridLayout
3 列。我正在使用 ItemTouchHelper 拖放 RecyclerView
的 GridLayout
。在我的适配器中有一个方法 onItemMove()
通知我我已经移动的项目。它只交换我拖放的 ArrayList
中的那些项目。但是由于拖放,其他元素也发生了变化。我也想更新他们在 ArrayList
.
这是我的 Recyclerview 的适配器:
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> implements com.sagar.quizdemo.helper.ItemTouchHelperAdapter {
String[] str = {"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"};
List<String> itemList, actualList;
LayoutInflater inflater;
Context context;
private final OnStartDragListener mDragStartListener;
public GridAdapter(Context context, OnStartDragListener dragStartListener) {
this.context = context;
mDragStartListener = dragStartListener;
inflater = LayoutInflater.from(context);
itemList = new ArrayList<>();
actualList = new ArrayList<>(Arrays.asList(str));
}
public void getItemList(List<String> nameList) {
int currentSize = itemList.size();
itemList.clear();
itemList.addAll(nameList);
notifyItemRangeRemoved(0, currentSize);
notifyItemRangeInserted(0, nameList.size());
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_level_row, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.textView.setText(itemList.get(position));
// Start a drag whenever the handle view it touched
holder.cardView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
}
return false;
}
});
}
@Override
public int getItemCount() {
return itemList.size();
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(itemList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
return true;
}
@Override
public void onItemDismiss(int position) {
itemList.remove(position);
notifyItemRemoved(position);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
CardView cardView;
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.gameCard);
textView = (TextView) itemView.findViewById(R.id.gameText);
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(Color.WHITE);
}
}
}
如果列表最初是:
{"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"}
在我交换 RecyclerView 中的第二个和第四个定位元素之后。更新后的列表应该如下所示(我想要的):
{"Level 1", "Level 5", "Level 2", "Level 3", "Level 4", "Level 6", "Level 7", "Level 8", "Level 9"}
但我收到了这个更新列表:
{"Level 1", "Level 5", "Level 3", "Level 4", "Level 2", "Level 6", "Level 7", "Level 8", "Level 9"}
尝试在 onItemMove 方法中调用 notifyDataSetChanged()。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
notifyDataSetChanged();
return true;
}
我认为您的问题在于您使用 Collections.swap(itemList, fromPosition, toPosition);
,它在指定位置交换对象。所以输出是正确的。不过,您需要的是:
String item = itemList.remove(fromPostion);
itemList.insert(item, toPosition);
试试这个。在您的情况下,您首先必须找到要替换的项目的索引 (fromPosition),然后将 toPosition 添加到该索引。 How to move specific item in array list to the first item
代码 here 为我工作。
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(listData, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(listData, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}