title: RecyclerView blank even after data loads
body: <p>I'm working on a <code>RecyclerView</code> within a <code>SwipeRefreshLayout</code>, which contains <code>CardViews</code> based on data retrieved from an API Call. This is implemented in a <code>Fragment</code> in one App and directly in the <code>Activity</code> in the other. </p>
  
  <p>While this code (with appropriate modifications) works fine in the <code>Activity</code>, the variant in the fragment always shows blank - even though I have validated that the data is received. Even seeding a dummy <code>CardView</code> doesn't get anything to show up. </p>
  
  <p>What am I doing wrong or missing?</p>
  
  <p><strong>The initialisation in OnCreateView is as follows:</strong></p>
  
  <pre><code>@Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                           Bundle savedInstanceState) {
      // Inflate the layout for this fragment
      View view = inflater.inflate (R.layout.fragment_revive_housecall, container, false);
      ...
      ...
      constraintLayout = view.findViewById (R.id.constraintLayout);
      swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById (R.id.swipeRefreshLayout);
      recyclerView = (RecyclerView) view.findViewById (R.id.recyclerView);
      emptyView = (TextView) view.findViewById (R.id.empty_view);
      houseCallList = new ArrayList&lt;&gt; ();
      adapter = new HouseCallAdapter (getActivity ().getApplicationContext (), houseCallList);
      if(houseCallList.isEmpty ()) {
          emptyView.setText (R.string.pulltorefresh);
          recyclerView.setVisibility (View.GONE);
          emptyView.setVisibility (View.VISIBLE);
      } else {
          //emptyView.setVisibility (View.GONE);
          recyclerView.setVisibility (View.VISIBLE);
          adapter.notifyDataSetChanged();
      }
      recyclerView.setLayoutManager (new LinearLayoutManager (getActivity ().getApplicationContext ()));
      recyclerView.setItemAnimator (new DefaultItemAnimator ());
      recyclerView.setAdapter (adapter);
      adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
  
          @Override
          public void onChanged() {
              super.onChanged();
              checkEmpty();
          }
  
          @Override
          public void onItemRangeInserted(int positionStart, int itemCount) {
              super.onItemRangeInserted(positionStart, itemCount);
              checkEmpty();
          }
  
          @Override
          public void onItemRangeRemoved(int positionStart, int itemCount) {
              super.onItemRangeRemoved(positionStart, itemCount);
              checkEmpty();
          }
  
          void checkEmpty() {
              emptyView.setText (R.string.no_data_available);
              emptyView.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
              recyclerView.setVisibility (adapter.getItemCount() == 0 ? View.GONE : View.VISIBLE);
          }
      });
      ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT /*| ItemTouchHelper.RIGHT*/, this);
      new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
      swipeRefreshLayout.setOnRefreshListener (new SwipeRefreshLayout.OnRefreshListener () {
          @Override
          public void onRefresh() {
              loadHouseCallRequests(null);  // in this function call onItemsLoadComplete when done
          }
      });
      return view;
  }
  </code></pre>
  
  <p><strong>The OnSwiped override is as follows:</strong></p>
  
  <pre><code>@Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
      if (viewHolder instanceof HouseCallAdapter.MyViewHolder) {
          // get the removed item name to display it in snack bar
          String housecallid = houseCallList.get(viewHolder.getAdapterPosition()).getHousecallid ();
  
          // backup of removed item for undo purpose
          final HouseCall deletedItem = houseCallList.get(viewHolder.getAdapterPosition());
          final int deletedIndex = viewHolder.getAdapterPosition();
  
          // remove the item from recycler view
          adapter.removeItem(viewHolder.getAdapterPosition());
          if (direction == ItemTouchHelper.LEFT) {
              ((HouseCallAdapter.MyViewHolder) viewHolder).viewBackground.setBackgroundColor (getResources ().getColor (R.color.bg_row_background_decline));
              // showing snack bar with Undo option
              Snackbar snackbar = Snackbar
                      .make(constraintLayout, "Request " + housecallid + " declined!", Snackbar.LENGTH_LONG);
              snackbar.setAction("UNDO", new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
  
                      // undo is selected, restore the deleted item
                      adapter.restoreItem(deletedItem, deletedIndex);
                  }
              });
              snackbar.setActionTextColor(Color.RED);
              snackbar.show();
          }
      }
  }
  
  void onItemsLoadComplete() {
      swipeRefreshLayout.setRefreshing(false);
  }
  
  private void loadHouseCallRequests(@Nullable JsonObject params) {
      // This is the code that generates the dummy cardview
      /*HouseCall call = new HouseCall ("abc123", "open", "12/02/1991", "26/02/2018:22:39", "general", "6", "XY", "AB", "ACB@XZY.com", "Male", "Line1", "Line2", "Line3", "City", "State", "123456789");
      houseCallList.add (call);*/
  
      adapter.notifyDataSetChanged();
      onItemsLoadComplete ();
      if (params == null) {
          params = new JsonObject ();
          params.addProperty ("email", email);
      }
      GetHouseCalls calls = new GetHouseCalls ();
      calls.execute (params);
  }
  </code></pre>
  
  <p><strong>The Adapter</strong></p>
  
  <pre><code>public class HouseCallAdapter extends RecyclerView.Adapter&lt;HouseCallAdapter.MyViewHolder&gt; {
  
  private Context mContext;
  private List&lt;HouseCall&gt; houseCallList;
  
  private static final int DATASET_EMPTY = 0;
  private static final int DATA_AVAILABLE = 1;
  
  
  public class MyViewHolder extends RecyclerView.ViewHolder{
  
      public TextView txtFname, txtLname, txtDob, txtSex, txtAddress, txtMobile;
      public ConstraintLayout viewBackground, viewForeground;
  
  
      public MyViewHolder(View itemView) {
          super (itemView);
          txtName = itemView.findViewById (R.id.txtName);
          ... // add data to the layout of the 
      }
  
  }
  
  public HouseCallAdapter(Context mContext, List&lt;HouseCall&gt; houseCallList) {
      this.mContext = mContext;
      this.houseCallList = houseCallList;
  }
  
  
  @Override
  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      View itemView = LayoutInflater.from (parent.getContext ())
              .inflate (R.layout.housecall_request, parent, false);
      return new MyViewHolder (itemView);
  }
  
  @Override
  public void onBindViewHolder(MyViewHolder holder, int position) {
      HouseCall houseCall = houseCallList.get (position);
      ... // retreive data from UI elements and set data in UI
  }
  
  
  @Override
  public int getItemCount() {
      return houseCallList.size ();
  }
  
  public void removeItem(int position) {
      houseCallList.remove(position);
      // notify the item removed by position
      // to perform recycler view delete animations
      // NOTE: don't call notifyDataSetChanged()
      notifyItemRemoved(position);
  }
  
  public void restoreItem(HouseCall item, int position) {
      houseCallList.add(position, item);
      // notify item added by position
      notifyItemInserted(position);
  }
  }
  </code></pre>
  
  <p><strong>Recycler Item Touch Helper</strong></p>
  
  <pre><code>public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
  private RecyclerItemTouchHelperListener listener;
  
  public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
      super(dragDirs, swipeDirs);
      this.listener = listener;
  }
  
  @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
      return true;
  }
  
  @Override
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
      if (viewHolder != null) {
          final View foregroundView = ((HouseCallAdapter.MyViewHolder) viewHolder).viewForeground;
  
          getDefaultUIUtil().onSelected(foregroundView);
      }
  }
  
  @Override
  public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                              RecyclerView.ViewHolder viewHolder, float dX, float dY,
                              int actionState, boolean isCurrentlyActive) {
      final View foregroundView = ((HouseCallAdapter.MyViewHolder) viewHolder).viewForeground;
      getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
              actionState, isCurrentlyActive);
  }
  
  @Override
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
      final View foregroundView = ((HouseCallAdapter.MyViewHolder) viewHolder).viewForeground;
      getDefaultUIUtil().clearView(foregroundView);
  }
  
  @Override
  public void onChildDraw(Canvas c, RecyclerView recyclerView,
                          RecyclerView.ViewHolder viewHolder, float dX, float dY,
                          int actionState, boolean isCurrentlyActive) {
      final View foregroundView = ((HouseCallAdapter.MyViewHolder) viewHolder).viewForeground;
  
      getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
              actionState, isCurrentlyActive);
  }
  
  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
      listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
  }
  
  @Override
  public int convertToAbsoluteDirection(int flags, int layoutDirection) {
      return super.convertToAbsoluteDirection(flags, layoutDirection);
  }
  
  public interface RecyclerItemTouchHelperListener {
      void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
  }
  }
  </code></pre>
  
  <p><strong>The layout xml</strong></p>
  
  <pre><code>&lt;android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.testapp.appname.FragmentCards"&gt;
  
  &lt;android.support.v4.widget.SwipeRefreshLayout
      android:id="@+id/swipeRefreshLayout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"&gt;
  
      &lt;TextView
          android:id="@+id/empty_view"
          android:layout_width="wrap_content"
          android:layout_height="18dp"
          android:gravity="center_vertical"
          android:text="@string/no_data_available"
          android:textAlignment="center"
          android:visibility="visible"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintHorizontal_bias="0.698"
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent"
          app:layout_constraintTop_toTopOf="parent" /&gt;
  
      &lt;android.support.v7.widget.RecyclerView
          android:id="@+id/recyclerView"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:scrollbars="vertical"
          android:visibility="visible" /&gt;
  
  &lt;/android.support.v4.widget.SwipeRefreshLayout&gt;
  </code></pre>
  
  <p></p>