【问题标题】:Android RecyclerView prevent recycling all itemsAndroid RecyclerView 阻止回收所有项目
【发布时间】: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


【解决方案1】:

问题是你应该交换ListAdapter.mDiffer 中的项目,它包含当前的显示列表。因此,您的代码中的globalItemList 未使用。将适配器的onRowMoved 替换为以下之一:

@Override
public void onRowMoved(int fromPosition, int toPosition) {
    ArrayList<Shoppinglist> list = new ArrayList(getCurrentList());
    Collections.swap(list, fromPosition, toPosition);
    submitList(list);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多