RecyclerView not updating its views when updated with new data
<p>I have a RecyclerView with a RecyclerView.Adapter implementation, which has a list of objects plus a header and a footer view, and I am switching on the viewType to show header for position 0 and footer for position getItemCount() (my "getItemCount()" implementation returns "data.size() + 2" to accommodate for header and footer). This all works great, the header and foot are shown at the correct places, but when I reach the end of the list and the footer is shown, I load more data and add that to my "data" list, and then I want the footer view to be replaced with the next loaded data view, but this does not happen. I have tried with alle the different "notifyX" methods on the adapter, but it seems that it does not get updated until i scroll the list (and then it all works as I want).</p>

<p>What am I missing here? How do I force the RecyclerView to redraw the last element in the list?</p>

<p>My adapter:</p>

<pre><code>private class TransactionsAdapter extends RecyclerView.Adapter {
        private List transactions;

        private static final int TYPE_HEADER = 0;
        private static final int TYPE_ITEM = 1;
        private static final int TYPE_FOOTER = 2;

        private TransactionsAdapter(List transactions) {
            this.transactions = transactions;
        }

        public void add(Transaction transaction) {
            transactions.add(transaction);
            notifyItemInserted(transactions.size());
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if(viewType == TYPE_HEADER) {
                ViewHolder vh = new ViewHolder(inflate(getContext(), R.layout.postings_list_header, null), TYPE_HEADER);
                return vh;
            } else if(viewType == TYPE_FOOTER) {
                ViewHolder vh = new ViewHolder(inflate(getContext(), R.layout.postings_list_footer, null), TYPE_FOOTER);
                return vh;
            }
            SlidingCellView cellView = new SlidingCellView(getContext());
            cellViews.add(cellView);
            ViewHolder vh = new ViewHolder(cellView, TYPE_ITEM);
            return vh;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            if (holder.getType() == TYPE_HEADER) {
                final TextView text = (TextView) holder.itemView.findViewById(R.id.postings_header_text);
                text.setText("Dette er nu godt");
            } else if (holder.getType() == TYPE_ITEM) {
                final Transaction transaction = transactions.get(position - 1);

                ((SlidingCellView) holder.itemView).update(new SlidingCellView.SlidingCellViewResources() {
                    @Override
                    public String getSlidingCellName() {
                        return transaction.getText();
                    }
                });
            } else if (holder.getType() == TYPE_FOOTER) {
                final TextView text = (TextView) holder.itemView.findViewById(R.id.no_more_postings);
                if(transactions.size() == 0) {
                    text.setText(getResources().getString(R.string.no_postings));
                } else {
                    if(resources.getTransactions().hasMore()) {
                        text.setText(getResources().getString(R.string.more_postings));
                    } else {
                        text.setText(getResources().getString(R.string.end_of_postings));
                    }
                }
            }
        }

        @Override
        public int getItemCount() {
            return transactions.size() + 2;
        }

        @Override
        public int getItemViewType(int position) {
            if(position == 0) {
                return TYPE_HEADER;
            }
            if(position == transactions.size() + 1) {
                return TYPE_FOOTER;
            }
            return TYPE_ITEM;
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            private int type;

            public ViewHolder(View itemView, final int type) {
                super(itemView);
                this.type = type;
            }

            public int getType() {
                return type;
            }
        }

    }</code></pre>

<p>Code that add to transactions:</p>

<pre><code>public void transactionsAdded() {
        for (Transaction trans : resources.getTransactions()) {
            postingsListAdapter.add(trans);
        }
    }</code></pre>

<p>So, if I scroll to the bottom of the list, the "R.layout.postings_list_footer" view is correctly displayed at the bottom of the list, then when the service call returns (code not shown) the "transactionsAdded" gets called and I would expect the list to redraw itself and thus draw the last shown element as a normal item and not a footer, but this only happens when I start to scroll in the list.
Thank you<br>
Søren</p>