RecyclerView notifyItemInserted 重复了之前条目的数据

6
所以,出于某种原因,每当我向我的ArrayList中添加新项目并通知recyclerview已添加时,它会复制先前条目的数据。这样视图就会创建,但使用的是上一个条目的数据而不是当前数据。
奇怪的是,我使用ORM Sugar保存项目,所以当我检索它们时,正确的数据被显示出来。这表明数据正在被添加,但是视图没有正确显示它。
我只能假设当我使用notifyItemInserted方法时,recyclerview没有调用onBindViewHolder,因为当我使用notifyDataSetChange()时显示了正确的数据。
以下是我的添加新项目的方法:
@Override
    public void AddCalorieToHistoryList(int calorieAmount, int currentCalorieAmount) {
        // Get the date and the calorie amount from what the user entered.
        Date date = new Date();
        // Create the calorie history item and then save it (via ORM Sugar Library)
        CalorieHistory calorieHistory = new CalorieHistory(date.toString(), calorieAmount);
        calorieHistory.save();

        // Notify the view of the new item that should be inserted.
        historyView.InsertNewListItem(calorieHistory);

        SubtractFromCurrentCalorieAmount(calorieAmount, currentCalorieAmount);
    }

historyView的方法

@Override
    public void InsertNewListItem(CalorieHistory calorieHistoryItem) {
        // Add the new item
        calorieHistories.add(calorieHistoryItem);
        // Notify the insert so we get the animation from the default animator
        historyListAdapter.notifyItemInserted(0);
    }

这是RecyclerView适配器的代码:

public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.HistoryListViewHolder> {

    List<CalorieHistory> calorieHistoryList;


    public HistoryListAdapter(List<CalorieHistory> historyList) {
        this.calorieHistoryList = historyList;
    }

    // I think this is run once, it generates the view holder from the layout that we are using for each list item.
    // This way it won't have to grab it each time we make a new list item. It's all stored on our view holder.
    @Override
    public HistoryListViewHolder onCreateViewHolder(ViewGroup parent, int i) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.calorie_history_item, parent, false);

        return new HistoryListViewHolder(itemView);
    }

    // This executes everytime we make a new list item, it binds the data to the view.
    @Override
    public void onBindViewHolder(HistoryListViewHolder holder, int position) {
        // Get the current calorHistory object and set it's data to the views.
        CalorieHistory calorieHistory = calorieHistoryList.get(position);
        holder.tvDate.setText(calorieHistory.date);
        holder.tvAmount.setText(String.valueOf(calorieHistory.numberOfCalories));
    }

    @Override
    public int getItemCount() {
        // Return the size of our array.
        return calorieHistoryList.size();
    }

    public static class HistoryListViewHolder extends RecyclerView.ViewHolder {
        public TextView tvDate;
        public TextView tvAmount;

        public HistoryListViewHolder(View v) {
            super(v);
            tvDate = (TextView) v.findViewById(R.id.calorie_date);
            tvAmount = (TextView) v.findViewById(R.id.calorie_amount);
        }
    }

}
1个回答

9

根据列表规范,List.add(E object) 应该将项目添加到列表末尾。您似乎正在将项目添加到末尾,但通知在第一个项目上进行插入。

为了将项目作为第一项添加,您应该进行更改:

calorieHistories.add(calorieHistoryItem);

为了

calorieHistories.add(0, calorieHistoryItem);

编辑

或者,如果你的确是想将项目添加到末尾,那么你应该更改

historyListAdapter.notifyItemInserted(0);

to

historyListAdapter.notifyItemInserted(calorieHistories.size()-1);

请注意,您应该首先将项目插入到列表中,然后更新项目计数整数(getItemCount),最后调用notifyItemInserted/Removed/DatasetChanged。我的问题是我在实际插入ArrayList之前就调用了item inserted,导致了与提问者描述的相同的重复症状。 - Ezequiel Adrian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接