【发布时间】:2020-11-10 18:14:19
【问题描述】:
我有一个 RecyclerView,用户可以在其中将项目拖放到 RecyclerView 中的不同位置。
到目前为止一切正常。
当 RecyclerView 的项目多于它可以显示时,我的问题就开始了。所以当它回收他的内容。当用户将项目拖放到不同的位置并且从该部分滚动离开时,不会保存位置更改。用户只看到项目的旧位置。
您可以在下面的 .gif 中看到这个问题。
我已经尝试了几件事,例如:
recyclerViewItem.getRecycledViewPool().setMaxRecycledViews(0,0);
recyclerViewItem.setItemViewCacheSize(30);
和
holder.setIsRecyclable(false);
在我的 onBindViewHolder 内部。
但似乎没有什么对我有用。
有人知道这个问题的解决方案吗?
我的片段类:
public class ShoppinglistFragment extends Fragment {
private ViewModel viewModel;
private ShoppinglistAdapter adapterShoppingItem = new ShoppinglistAdapter();
private RecyclerView recyclerViewItem;
private Boolean fragmentStarted = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.shoppinglist_layout, container, false);
recyclerViewItem = view.findViewById(R.id.recyclerViewShoppinglist);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(getActivity()).get(ViewModel.class);
fragmentStarted = true;
recyclerViewItem.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerViewItem.setHasFixedSize(false);
recyclerViewItem.getRecycledViewPool().setMaxRecycledViews(0,0);
recyclerViewItem.setItemViewCacheSize(30);
recyclerViewItem.setAdapter(adapterShoppingItem);
ItemTouchHelper.Callback callback =
new ItemMoveCallback(adapterShoppingItem);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerViewItem);
//fetch all Shoppinglist Items from local storage
viewModel.getAllShoppinglistItems().observe((LifecycleOwner) this, new Observer <List<Shoppinglist>>() {
@Override
public void onChanged(@Nullable List<Shoppinglist> items) {
if (fragmentStarted){
adapterShoppingItem.submitList(items);
fragmentStarted = false;
}
}
});
adapterShoppingItem.setOnPositionChanged(new ShoppinglistAdapter.onPositionChanged() {
@Override
public void onPositionChanged(Shoppinglist fromItem, Shoppinglist toItem, int fromPosition, int toPosition) {
int fromPositionServer = fromItem.getPosition();
int toPositionServer = toItem.getPosition();
fromItem.setPosition(toPositionServer);
toItem.setPosition(fromPositionServer);
//updating Shoppinglist Item locally
viewModel.updateItem(fromItem);
viewModel.updateItem(toItem);
}
});
}
}}
和我的适配器类:
public class ShoppinglistAdapter extends ListAdapter<Shoppinglist, ShoppinglistAdapter.NoteHolder> implements ItemMoveCallback.ItemTouchHelperContract {
public Integer ressourceType;
private onPositionChanged onPositionChanged;
private ArrayList<Shoppinglist> globalItemList = new ArrayList<Shoppinglist>();
public ShoppinglistAdapter() {
super(DIFF_CALLBACK);
Integer valueOf = Integer.valueOf(0);
this.ressourceType = valueOf;
}
private static final DiffUtil.ItemCallback<Shoppinglist> DIFF_CALLBACK = new DiffUtil.ItemCallback<Shoppinglist>() {
@Override
public boolean areItemsTheSame(Shoppinglist oldItem, Shoppinglist newItem) {
return oldItem.getSqlid() == newItem.getSqlid();
}
@Override
public boolean areContentsTheSame(Shoppinglist oldItem, Shoppinglist newItem) {
return oldItem.getTitle().equals(newItem.getTitle());
}
};
@NonNull
@Override
public NoteHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.shoppinglist_item, parent, false);
return new NoteHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull NoteHolder holder, int position) {
Shoppinglist currentItem = getItem(position);
holder.setIsRecyclable(false);
holder.tv.setText(currentItem.getTitle());
...
}
public Shoppinglist getNoteAt(int position) {
return getItem(position);
}
public class NoteHolder extends RecyclerView.ViewHolder {
private TextView tv;
public NoteHolder(View itemView) {
super(itemView);
tv= itemView.findViewById(R.id.tv);
globalItemList .add(currentNote);
}
}
public interface onPositionChanged {
void onPositionChanged(Shoppinglist fromItem, Shoppinglist toItem, int fromPosition, int toPosition);
}
public void setOnPositionChanged(ShoppinglistAdapter.onPositionChanged listener) {
this.onPositionChanged = listener;
}
@Override
public void onRowMoved(int fromPosition, int toPosition) {
//send switched Items to Fragment
onPositionChanged.onPositionChanged(globalItemList.get(fromPosition), globalItemList.get(toPosition), fromPosition, toPosition);
//switch Items inside of the global Item List
Collections.swap(globalItemList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onRowSelected(NoteHolder myViewHolder) {}
@Override
public void onRowClear(NoteHolder myViewHolder) {}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
【问题讨论】:
-
以上
ShoppinglistAdapter是否完整?除了onRowMoved(),你在哪里使用globalItemList? -
我在这里填写这个列表: public NoteHolder(View itemView) { super(itemView); tv= itemView.findViewById(R.id.tv); globalItemList .add(currentNote); } @氨基摄影
-
它不应该在那里!
ListAdapter是您的自定义类吗? (如果是,也发布它的代码)你知道,问题是你应该交换AsyncListDiffer列表中的项目,而不是globalItemList。 -
No ListAdapter 不是自定义类。我不明白这个问题。
标签: java android android-studio android-recyclerview