title: RecyclerView not updating after adding when data was empty
body: <p>I'm facing a strange problem when using the recylerview inside a linearlayout inside a cardview. It works perfectly when the initial data I'm passing into the adapter/recyclerview is not empty. But when I try to add an item dynamically (when the initial data was empty), the adapter set's the items, call's notifyDataSetChanged, but the recyclerview stays empty. </p>
  
  <p>If I add the data dynamically, when the initial Collection was not empty, it works perfectly. It's working on other views as well. Anybody an idea what the problem could be? </p>
  
  <p>Thanks in advance!</p>
  
  <p>The XML file:</p>
  
  <pre><code>&lt;layout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      xmlns:card_view="http://schemas.android.com/apk/res-auto"
      xmlns:app="http://schemas.android.com/apk/res-auto"&gt;
      &lt;data&gt;
      &lt;/data&gt;
  
      &lt;LinearLayout
          android:id="@+id/main_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical"&gt;
  
  
          &lt;android.support.v7.widget.Toolbar
              android:id="@+id/toolbarComposer"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@color/colorPrimary"
              android:elevation="4dp"
              app:title="@string/title_timeline"
              app:titleTextColor="@color/white"
              app:navigationIcon="@drawable/ic_arrow_back_black_24dp"
              &gt;
  
          &lt;/android.support.v7.widget.Toolbar&gt;
  
  
          &lt;android.support.v4.widget.SwipeRefreshLayout
              android:id="@+id/refreshLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/intercomsdk_white"&gt;
  
              &lt;ScrollView
                  android:id="@+id/scrollView"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:padding="7dp"
                  android:background="#E1E2E4"&gt;
  
                  &lt;LinearLayout
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:orientation="vertical"&gt;
  
                      &lt;include android:id="@+id/messageCardView" layout="@layout/item_timeline_message"/&gt;
  
                      &lt;android.support.v7.widget.CardView
                          android:layout_width="match_parent"
                          android:layout_height="match_parent"
                          card_view:cardElevation="3sp"
                          card_view:cardUseCompatPadding="true"
                          android:layout_marginTop="-10dp"&gt;
  
                          &lt;LinearLayout
                              android:layout_width="match_parent"
                              android:layout_height="match_parent"
                              android:orientation="vertical"&gt;
  
                              &lt;android.support.v7.widget.RecyclerView
                                  android:id="@+id/commentRecyclerView"
                                  android:layout_width="match_parent"
                                  android:layout_height="0dp"
                                  android:background="#E1E2E4"
                                  tools:listitem="@layout/item_timeline_comment"
                                  android:layout_above="@+id/commentContainer"
                                  android:minHeight="10dp"
                                  android:layout_weight="1"
                                  /&gt;
  
                              &lt;LinearLayout
                                  android:id="@+id/commentContainer"
                                  android:layout_width="match_parent"
                                  android:layout_height="wrap_content"
                                  android:orientation="horizontal"
                                  android:background="@color/chatWhite"&gt;
  
                                  &lt;EditText
                                      android:id="@+id/commentTextField"
                                      android:layout_width="0dp"
                                      android:layout_height="wrap_content"
                                      android:textColorHint="@color/chatTextGray"
                                      android:textSize="14dp"
                                      android:layout_marginTop="10dp"
                                      android:layout_marginLeft="10dp"
                                      android:paddingBottom="15dp"
                                      android:layout_weight="0.8"
                                      android:hint="@string/commentInputHint" /&gt;
  
                                  &lt;ImageButton
                                      android:id="@+id/sendButton"
                                      android:layout_width="wrap_content"
                                      android:layout_height="wrap_content"
                                      android:text="Verstuur"
                                      android:src="@drawable/ic_send_button"
                                      android:layout_gravity="center"
                                      android:layout_marginRight="5dp"
                                      android:tint="@color/chatSendButtonTint"
                                      android:background="@color/chatWhite"
                                      /&gt;
  
                              &lt;/LinearLayout&gt;
  
                          &lt;/LinearLayout&gt;
                      &lt;/android.support.v7.widget.CardView&gt;
  
                  &lt;/LinearLayout&gt;
  
              &lt;/ScrollView&gt;
  
          &lt;/android.support.v4.widget.SwipeRefreshLayout&gt;
  
      &lt;/LinearLayout&gt;
  &lt;/layout&gt;
  </code></pre>
  
  <p>The activity:</p>
  
  <pre><code>public class TimelineMessageActivity extends BaseActivity implements TimelineMessagePresenter.ViewInterface {
  
      private TimelineMessagePresenter presenter;
      private TimelineCommentAdapter adapter;
  
      private TimelineDataManager timelineDataManager;
      private NetworkClientInterface timelineNetworkClient;
      private UserSettingsStoreInterface userSettingsStore;
  
      private FragmentTimelineMessageBinding binding;
      private Menu menu;
      public int messageId;
  
      private List&lt;TimelineCommentModel&gt; comments = new ArrayList&lt;&gt;();
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          this.userSettingsStore = new UserSettingsStore(getModel().getEnvironment());
          this.timelineNetworkClient = new NetworkClient(getModel().getEnvironment(), getModel().getCredentialStore());
          this.timelineDataManager = new TimelineDataManager(getModel().getTimelineStore(), timelineNetworkClient);
  
          binding = DataBindingUtil.setContentView(this, R.layout.fragment_timeline_message);
  
          adapter = new TimelineCommentAdapter(new TimelineCommentAdapter.Listener() {
              @Override
              public void didClickProfileImage(TimelineCommentModel item) {
  
              }
  
              @Override
              public void didClickMention(int userId) {
                  presenter.didClickMention(userId);
              }
          }, getModel());
  
          SlideInBottomAnimatorAdapter animatorAdapter = new SlideInBottomAnimatorAdapter(adapter, binding.commentRecyclerView);
          binding.commentRecyclerView.setItemAnimator(new SlideInOutLeftItemAnimator(binding.commentRecyclerView));
          binding.commentRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
  
          binding.commentRecyclerView.setAdapter(animatorAdapter);
          binding.commentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  
          binding.refreshLayout.setOnRefreshListener(() -&gt; presenter.refreshMessage());
          binding.refreshLayout.setRefreshing(true);
  
          presenter = new TimelineMessagePresenter(getModel(), getRouter(), this.timelineDataManager);
          if(getIntent().getIntExtra("message_id", 0) &gt; 0){
              presenter.setMessageId(getIntent().getIntExtra("message_id", 0));
          }
      }
  
      @Override
      public void onDestroy() {
          presenter = null;
          super.onDestroy();
      }
  
      @Override
      public void onStart() {
          super.onStart();
          presenter.attachView(this);
          presenter.refreshMessage();
      }
  
      @Override
      public void onStop() {
          presenter.detachView();
  
          View view = this.getCurrentFocus();
          if (view != null) {
              InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
              imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
          }
  
          super.onStop();
      }
  
      @Override
      public void setComments(List&lt;TimelineCommentModel&gt; items) {
  
          for(TimelineCommentModel model : items) {
              this.comments.add(model);
          }
  
          adapter.setItems(this.comments);
          binding.refreshLayout.setRefreshing(false);
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          switch (item.getItemId()) {
              default:
                  return super.onOptionsItemSelected(item);
          }
      }
  
      @Override
      public void setTitle(int title){
          this.getSupportActionBar().setTitle(this.getString(title));
      }
  
      @Override
      public void setEditText(String text) {
          binding.commentTextField.setText(text);
      }
  
      @Override
      public void setButtonEnabled(boolean enabled) {
          binding.sendButton.setEnabled(enabled);
          binding.sendButton.setAlpha((float) (enabled ? 1.0 : 0.5));
      }
  
      @Override
      public void didSendComment() {
          binding.commentTextField.setText("");
          presenter.refreshMessage();
      }
  
      public void setMessageId(int messageId){
          this.messageId = messageId;
      }
  
      public void didClickMention(int userId){
          getRouter().openUri(Uri.parse("flexappeal://users/"+userId));
      }
  
      public void didClickDeleteButton(int id){
          AlertDialog.Builder dialog = new AlertDialog.Builder(this);
          dialog.setMessage(getString(R.string.confirm_delete_message));
          dialog.setNegativeButton(R.string.no, (dialogInterface, i) -&gt; {
              dialogInterface.dismiss();
          });
          dialog.setPositiveButton(R.string.yes, (dialogInterface, i) -&gt; {
              presenter.didClickDeleteButton(id);
          });
          dialog.show();
      }
  
      @Override
      public void didClickBackButton(){
          this.finish();
      }
  }
  </code></pre>
  
  <p>The presenter:</p>
  
  <pre><code>public class TimelineMessagePresenter extends BasePresenter&lt;TimelineMessagePresenter.ViewInterface&gt; {
  
      interface ViewInterface extends BasePresenter.ViewInterface {
          void setComments(List&lt;TimelineCommentModel&gt; items);
  
          void setTitle(int title);
          void didSendComment();
  
          void setButtonEnabled(boolean enabled);
          void setEditText(String text);
  
          void didClickBackButton();
      }
  
      private TimelineViewModel message = new TimelineViewModel();
      private List&lt;TimelineCommentModel&gt; comments = new ArrayList&lt;&gt;();
      private String commentMessage;
  
      private int messageId;
  
      @NonNull private final TimelineDataManager dataManager;
  
      private final boolean needsRefresh = true;
  
      public TimelineMessagePresenter(@NonNull Model model, @NonNull RouterInterface router, @NonNull TimelineDataManager dataManager) {
          super(model, router);
          this.dataManager = dataManager;
      }
  
      @Override
      protected void onAttachView() {
          super.onAttachView();
  
          getModel().getEventBus().register(this);
  
          updateView();
      }
  
      @Override
      protected void onDetachView() {
          getModel().getEventBus().unregister(this);
  
          super.onDetachView();
      }
  
      @Subscribe
      public void onEvent(SocketEvent event) {
          // TODO: handle new comment in message event as soon as we integrate realtime timeline as well
      }
  
      public void updateView() {
          if (getView() != null) {
              getView().setEditText(commentMessage);
              getView().setComments(comments);
          }
      }
  
      private boolean shouldEnableButton() {
          return (commentMessage != null &amp;&amp; commentMessage.length() &gt; 0);
      }
  
      public void didClickHighFiveButton(){
          dataManager.postLike(messageId).subscribe(message -&gt; {
              refreshMessage();
          }, error -&gt; {
              Log.w("TimelinePresenter", error);
          });
      }
  
      public void didClickSendCommentButton(){
          this.dataManager.postComment(messageId, commentMessage).subscribe(result -&gt; {
              getView().didSendComment();
          }, error -&gt; {
              Log.w("TimelinePresenter", error);
          });
      }
  
      public void refreshMessage() {
          dataManager.getMessageDetail(messageId).subscribe(messageDetail -&gt;{
              this.comments.clear();
  
              this.message = createViewModelForTimelineMessage(messageDetail);
              if(messageDetail.getComments() != null){
                  for(Comments comment : messageDetail.getComments()) {
                      this.comments.add(createViewModelForTimelineComment(comment));
                  }
              }
              updateView();
          }, error -&gt; {
              Log.w("TimelineMessagePresenter", error);
          });
  
      }
  
      private TimelineCommentModel createViewModelForTimelineComment(Comments c) {
          TimelineCommentModel vm = new TimelineCommentModel();
          vm.commentId = c.getId();
          vm.createdBy = c.getUser();
          vm.createdAt = c.getCreated_at_diff();
          vm.message = c.getMessage();
  
          return vm;
      }
  
      public void didChangeMessage(CharSequence message) {
          this.commentMessage = message.toString();
  
          if (getView() != null) {
              getView().setButtonEnabled(shouldEnableButton());
          }
      }
  
      public void setMessageId(int messageId){
          this.messageId = messageId;
      }
  
      public void didClickMention(int userId){
          getRouter().openUri(Uri.parse("flexappeal://users/"+userId));
      }
  
      public void didClickDeleteButton(int id){
          dataManager.deleteMessage(id).subscribe(aBoolean -&gt; {
              getView().didClickBackButton();
          }, error -&gt; {
              getView().didClickBackButton();
          });
      }
  }
  </code></pre>
  
  <p>The adapter:</p>
  
  <pre><code>class TimelineCommentAdapter extends BindingRecyclerViewAdapter&lt;TimelineCommentModel, ItemTimelineCommentBinding&gt; {
  
      private final Listener listener;
      private final Model model;
  
      public TimelineCommentAdapter(Listener listener, Model model) {
          super(R.layout.item_timeline_comment);
          this.listener = listener;
          this.model = model;
      }
  
      public interface Listener {
          void didClickProfileImage(TimelineCommentModel item);
          void didClickMention(int userId);
      }
  
      @Override
      protected void bind(ItemTimelineCommentBinding binding, TimelineCommentModel item, int position) {
  
          Picasso.with(binding.getRoot().getContext()).load(item.createdBy.getProfileImage()).into(binding.userProfileImage);
          binding.userProfileImage.setOnClickListener(view -&gt; listener.didClickProfileImage(item));
  
          binding.userFullName.setText(item.createdBy.getFullName());
          binding.ago.setText(item.createdAt);
  
      }
  
      @Override
      protected void recycle(ItemTimelineCommentBinding binding) {
          Picasso.with(binding.getRoot().getContext()).cancelRequest(binding.userProfileImage);
      }
  }
  </code></pre>
  
  <p>The BindingRecyclerViewAdapter:</p>
  
  <pre><code>public abstract class BindingRecyclerViewAdapter&lt;T, B extends ViewDataBinding&gt;
          extends RecyclerView.Adapter&lt;BindingRecyclerViewAdapter&lt;T, B&gt;.ViewHolder&gt; {
  
      public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
          public final B binding;
  
          public ViewHolder(B binding) {
              super(binding.getRoot());
              this.binding = binding;
              this.itemView.setOnClickListener(this);
          }
  
          @Override
          public void onClick(View view) {
              if (onItemClickListener != null) {
                  int position = getAdapterPosition();
                  if (position != RecyclerView.NO_POSITION) {
                      onItemClickListener.onItemClick(view, position);
                  }
              }
          }
      }
  
      public interface OnItemClickListener {
          void onItemClick(View itemView, int position);
      }
  
      private OnItemClickListener onItemClickListener;
      private List&lt;T&gt; items;
  
      private final int layoutRes;
  
      public BindingRecyclerViewAdapter(@LayoutRes int layoutRes) {
          this(layoutRes, null, null);
      }
  
      public BindingRecyclerViewAdapter(@LayoutRes int layoutRes, Collection&lt;T&gt; items) {
          this(layoutRes, items, null);
      }
  
      public BindingRecyclerViewAdapter(@LayoutRes int layoutRes, Collection&lt;T&gt; items, OnItemClickListener onItemClickListener) {
          this.layoutRes = layoutRes;
          this.items = (items == null) ? new ArrayList&lt;&gt;() : new ArrayList&lt;&gt;(items);
          this.onItemClickListener = onItemClickListener;
      }
  
      @Override
      public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          B binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), layoutRes, parent, false);
          return new ViewHolder(binding);
      }
  
      @Override
      public void onBindViewHolder(ViewHolder holder, int position) {
          T item = items.get(position);
          bind(holder.binding, item, position);
      }
  
      @Override
      public void onViewRecycled(ViewHolder holder) {
          recycle(holder.binding);
      }
  
      @Override
      public int getItemCount() {
          return items.size();
      }
  
      protected abstract void bind(B binding, T item, int position);
      protected abstract void recycle(B binding);
  
      public OnItemClickListener getOnItemClickListener() {
          return onItemClickListener;
      }
  
      public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
          this.onItemClickListener = onItemClickListener;
      }
  
      public List&lt;T&gt; getItems() {
          return items;
      }
  
      public void setItems(Collection&lt;T&gt; items) {
          this.items.clear();
  
          if (items != null) {
              this.items.addAll(items);
          }
  
          notifyDataSetChanged();
      }
  
  }
  </code></pre>