EmptyView for recyclerView

fragment_crime_list

<android.support.v7.widget.RecyclerView
    android:id="@+id/crime_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>

    <TextView
        android:id="@+id/emptyTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:text="There are no Crimes" />

Can some body help me how to check if RecyclerView is empty or not to show empty view instead?
thanks in advance

First, you’ll need your empty view to be defined outside of your RecyclerView in your layout file. Something like:

<FrameLayout>
  <RecyclerView />
  <TextView />
</FrameLayout>

To figure out when to show the empty view, you can check the size of your crimes list in the updateUI method.

Thanks for the reply.
I did the same thing and i chekced crime count and if it is greater than zero i am making the textview invisible but somehow the textview does not get invisible.It stays Visible

Can you post that part of your code here?

I have figured it out but not in the correct way.I am making the textview invisible on click of New Crime method.Below is the code.Let me know if there is a better way
fragment_crime_list

<TextView
    android:id="@+id/emptyTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerInParent="true"
    android:text="There are no Crimes" />

<android.support.v7.widget.RecyclerView
    android:id="@+id/crime_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>

CrimeListFragment
package pritish.sawant.com.criminalintent;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static android.media.CamcorderProfile.get;

/**

  • A simple {@link Fragment} subclass.
    */
    public class CrimeListFragment extends Fragment {

    private RecyclerView recyclerView;
    private CrimeAdapter crimeAdapter;
    private boolean subtitleVisible;
    public int CurrentPosition;
    public static final String SUBTITLE=“subtitle”;
    private TextView emptyView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     setHasOptionsMenu(true);
    

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view=inflater.inflate(R.layout.fragment_crime_list,container,false);

     if(savedInstanceState!=null){
         subtitleVisible=savedInstanceState.getBoolean(SUBTITLE);
     }
    
     recyclerView=(RecyclerView)view.findViewById(R.id.crime_recycler_view);
     recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    
     emptyView=(TextView)view.findViewById(R.id.emptyTextView);
    
     updateUI();
     return view;
    

    }

    @Override
    public void onResume() {
    super.onResume();

     //UpDateUi is called in onResume because When CrimeListFragment starts an instance of CrimeActivity , the CrimeActivity is put on top of
     //   the stack. This pauses and stops the instance of CrimeListActivity that was initially on top.
     //         When the user presses the Back button to return to the list, the CrimeActivity is popped off the stack
     // and destroyed. At that point, the CrimeListActivity is started and resumed
     updateUI();
    

    }

    private void updateUI(){
    CrimeLab crimeLab=CrimeLab.get(getActivity());
    List crimes= crimeLab.getCrimeList();
    if(crimeAdapter==null){
    crimeAdapter=new CrimeAdapter(crimes);
    recyclerView.setAdapter(crimeAdapter);

     }
     //NotifyDataSetChanged has been called beacuse when you click on CrimeList and go to particular Crime and update that crime
     //and press back button that updated crime should be displayed in the list
     else{
    
         //We are updating only one item at a time so using notifyDataSetChanged would be insufficient as it updates all the items
         //so use notifyItemChanged to update only that item which has changed
         //crimeAdapter.notifyDataSetChanged();
    
         crimeAdapter.setCrimes(crimes);
         crimeAdapter.notifyItemChanged(CurrentPosition);
    
     }
     updateSubtitle();
    

    }

    public class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

     private TextView tileTextView,dateTextView;
     private CheckBox checkBox;
     private Crime mcrime;
    
     public CrimeHolder(View itemView) {
         super(itemView);
         itemView.setOnClickListener(this);
    
    
         tileTextView=(TextView)itemView.findViewById(R.id.list_item_crime_textview);
         dateTextView=(TextView)itemView.findViewById(R.id.list_item_date_textview);
         checkBox=(CheckBox)itemView.findViewById(R.id.list_item_crime_checkbox);
     }
    
     public void bindCrime(Crime crime){
         mcrime=crime;
         tileTextView.setText(crime.getTitle());
         dateTextView.setText(crime.getDate().toString());
         checkBox.setChecked(crime.isSolved());
     }
    
    
     @Override
     public void onClick(View v) {
         Toast.makeText(getActivity(),"You clicked on "+mcrime.getTitle(),Toast.LENGTH_LONG).show();
         CurrentPosition=getAdapterPosition();
         Intent intent = CrimePagerActivity.newIntent(getActivity(), mcrime.getUuid());
         startActivity(intent);
     }
    

    }

    public class CrimeAdapter extends RecyclerView.Adapter{

     private List<Crime> crimeList;
     public CrimeAdapter(List<Crime> crimes){
         crimeList=crimes;
     }
    
     @Override
     public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
        View view= layoutInflater.inflate(R.layout.list_item_crime,parent,false);
         return new CrimeHolder(view);
     }
    
     @Override
     public void onBindViewHolder(CrimeHolder holder, int position) {
         Crime  crime= crimeList.get(position);
         holder.bindCrime(crime);
     }
    
     @Override
     public int getItemCount() {
         return crimeList.size();
     }
    
     //this is used in case of Sqlite databse so that when you add a crime and change it ,it should be updated
     //call this method in updateUI also
     public void setCrimes(List<Crime> crimes){
         crimeList=crimes;
     }
    

    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_main,menu);

     MenuItem menuItem=menu.findItem(R.id.menu_item_show_title);
     if(subtitleVisible){
         menuItem.setTitle(R.string.hide_subtitle);
     }
     else{
         menuItem.setTitle(R.string.show_subtitle);
     }
    

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
    case R.id.menu_item_new_crime:
    emptyView.setVisibility(View.GONE);
    Crime crime=new Crime();
    CrimeLab.get(getActivity()).addCrime(crime);
    Intent intent = CrimePagerActivity
    .newIntent(getActivity(), crime.getUuid());
    startActivity(intent);
    return true;
    case R.id.menu_item_show_title:
    subtitleVisible=!subtitleVisible;
    getActivity().invalidateOptionsMenu();
    updateSubtitle();
    return true;
    default:
    return super.onOptionsItemSelected(item);
    }
    }

    private void updateSubtitle(){
    AppCompatActivity appCompatActivity=(AppCompatActivity)getActivity();
    CrimeLab crimeLab=CrimeLab.get(getActivity());
    int count=crimeLab.getCrimeList().size();
    //String subtitle=getString(R.string.subtitle_format,String.valueOf(count));
    String subtitle=getResources().getQuantityString(R.plurals.subtitle_plural,count,count);
    if(!subtitleVisible){
    subtitle="";
    }
    appCompatActivity.getSupportActionBar().setSubtitle(subtitle);

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(SUBTITLE,subtitleVisible);
    }
    }

Actually this is competely wrong.Because if close the application,There are no crimes view appears again

I would put it in the updateUI method:

private void updateUI(){
    CrimeLab crimeLab=CrimeLab.get(getActivity());
    List<Crime> crimes= crimeLab.getCrimeList();
    
    emptyView.setVisibility((crimes.size() > 0? View.GONE : View.VISIBLE);    
    ...

1 Like

Thanks alot. Appreciate it