Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView notifyItemInserted duplicates previous entry's data

So for some reason whenever I add a new item to my ArrayList and notify the recyclerview that it's been added, it duplicates the previous entry's data. So the view gets created but with data from the last entry not the current data.

What's strange is that I save the items using ORM Sugar, and so when I retrieve them the correct data is displayed. Which shows that the data is getting added but the view is not showing it correctly.

I can only assume recyclerview is not calling the onBindViewHolder whenever I use the method notifyItemInserted, because the correct data is shown when I use notifyDataSetChange()

Here's my method to add the new item

@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's method

@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);
    }

Here's the recyclerview adapter

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);
        }
    }

}
like image 800
Max McKinney Avatar asked Sep 18 '15 02:09

Max McKinney


1 Answers

According to list specification, List.add(E object) should add the item to the END of the list. You seems to be adding item to the END, while notify insert on the FIRST item.

In order to add the item as the first item, you should change

calorieHistories.add(calorieHistoryItem);

to

calorieHistories.add(0, calorieHistoryItem);

Edit

Or, if you actually means to add the item to the END, you should change

historyListAdapter.notifyItemInserted(0);

to

historyListAdapter.notifyItemInserted(calorieHistories.size()-1);
like image 180
Derek Fung Avatar answered Oct 27 '22 15:10

Derek Fung