How to determine if RecyclerView is empty?

I have a RecyclerView receiving external JSON data parsed from a server. It works fine, but the Async Volley JSON task sometimes takes some time, and when it makes a fragment, an empty empty view is displayed.

How to create a test to check if a view is empty and displays a msg message, if any? I tried to check:

if (recyclerView == null) if (jsonList == null) if (adapter.getItemCount() == 0) if (bundle == null) 

But these tests either do nothing or display an error message every time, even if RecyclerView is not empty.

This is the fragment code:

 public void onViewCreated(View view, Bundle savedInstanceState) { LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.supportsPredictiveItemAnimations(); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setClickable(true); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); NovaAdapter novaAdapter = new NovaAdapter(getActivity(),jsonList); if (novaAdapter.getItemCount() != 0) { recyclerView.setAdapter(novaAdapter); }else{ pDialog = new ProgressDialog(getActivity()); pDialog.setMessage("Retrieving data from Server"); pDialog.show(); } super.onViewCreated(view, savedInstanceState); 

and adapter method:

 @Override public int getItemCount() { return (null != novaList ? novaList.size() : 0); } 

Now, as always, the execution dialog always starts regardless of whether it is empty or not.

UPDATE: here is the adapter code:

 public class NovaAdapter extends RecyclerView.Adapter<NovaListRowHolder> { ArrayList<HashMap<String, String>> novaList = new ArrayList<HashMap<String, String>>(); public static final String STATUS = "status"; public static final String NAME = "name"; public static final String ID = "id"; private Context mContext; public NovaAdapter(Context context, ArrayList<HashMap<String, String>> novaList) { this.novaList = novaList; this.mContext = context; } @Override public NovaListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.instances_list, null); NovaListRowHolder mh = new NovaListRowHolder(v); return mh; } @Override public void onBindViewHolder(NovaListRowHolder novaListRowHolder, int i) { HashMap<String, String> e = novaList.get(i); novaListRowHolder.name.setText(e.get(NAME)); novaListRowHolder.status.setText(e.get(STATUS)); novaListRowHolder.setId(e.get(ID)); } @Override public int getItemCount() { return (null != novaList ? novaList.size() : 0); }class NovaListRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ protected TextView name; protected TextView status; protected String id; public String getId() { return id; } public void setId(String id) { this.id = id; } public NovaListRowHolder(View view) { super(view); view.setOnClickListener(this); this.name = (TextView) view.findViewById(R.id.nameInstance); this.status = (TextView) view.findViewById(R.id.statusInstance); } public void onClick(View view){ Dialog dialog = new Dialog(view.getContext()); dialog.setContentView(R.layout.instances_listdetail); dialog.setTitle("Details " + name.getText() + " " + getPosition()); dialog.show(); } 

UPDATE2:

I updated another class, which is almost the same as above, with a callback interface, however now recyclerView displays for 1 second and then empty. The dialog is not even displayed. Here is the code:

 public class SubnetsFragment extends Fragment implements OnJSONLoaded{ /** * The fragment argument representing the section number for this * fragment. */ private static final String ARG_SECTION_NUMBER = "section_number"; private OnFragmentInteractionListener mListener; public ArrayList<HashMap<String, String>> jsonList; public RecyclerView recyclerView; public ProgressDialog pDialog; /** * Returns a new instance of this fragment for the given section * number. */ public static SubnetsFragment newInstance(int sectionNumber) { SubnetsFragment fragment = new SubnetsFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } public SubnetsFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle extras = getArguments(); Serializable parsedList = extras.getSerializable("SubnetsParsed"); jsonList = (ArrayList<HashMap<String, String>>)parsedList; if (extras == null){ AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); alert.setTitle("Token Expired"); alert.setMessage("Authentication Token expired! Please login again.") .setNeutralButton("Connect", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { Intent intent = new Intent(getActivity(), Login.class); startActivity(intent); getActivity().finish(); getFragmentManager().beginTransaction().remove(SubnetsFragment.this).commit(); } }); AlertDialog alertDialog = alert.create(); alertDialog.show(); } View rootView = inflater.inflate(R.layout.fragment_subnets, container, false); recyclerView = (RecyclerView)rootView.findViewById(R.id.subnetsRV); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.supportsPredictiveItemAnimations(); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setClickable(true); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); onJsonLoaded(jsonList); } @Override public void onJsonLoaded(ArrayList<HashMap<String, String>> list) { SubnetsParser.setOnJSONLoadedListener(new OnJSONLoaded() { @Override public void onJsonLoaded(ArrayList<HashMap<String, String>> list) { if (list.size() != 0){ SubnetsAdapter subnetsAdapter = new SubnetsAdapter(getActivity(),jsonList); recyclerView.setAdapter(subnetsAdapter); }else { pDialog = new ProgressDialog(getActivity()); pDialog.setMessage("Retrieving data from Server"); pDialog.show(); } } }); } @Override public void onAttach(Activity activity) { super.onAttach(activity); ((Stackerz) activity).onSectionAttached( getArguments().getInt(ARG_SECTION_NUMBER)); //try { // mListener = (OnFragmentInteractionListener) activity; //} catch (ClassCastException e) { // throw new ClassCastException(activity.toString() // + " must implement OnFragmentInteractionListener"); //} } @Override public void onDetach() { super.onDetach(); mListener = null; } /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ public interface OnFragmentInteractionListener { // TODO: Update argument type and name public void onFragmentInteraction(Uri uri); } } 

And this is the JSON Parser class:

 public class SubnetsParser extends Activity{ public static final String NAME = "name"; public static final String GW = "gw"; public static final String CIDR = "cidr"; public static final String ID = "id"; public String authToken; public String neutronURL; public static SubnetsParser parser = null; public static OnJSONLoaded mListener; public static void setOnJSONLoadedListener(OnJSONLoaded listener) { mListener = listener; } public interface OnJSONLoaded { void onJsonLoaded(ArrayList<HashMap<String, String>> list); } public static SubnetsParser shared(){ if (parser == null){ parser = new SubnetsParser(); } return parser ; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public static ArrayList<HashMap<String, String>> parseJSON(String subnetsJSON){ ArrayList<HashMap<String, String>> jsonList = new ArrayList<HashMap<String, String>>(); try { Subnets subnets = new Subnets(); JSONObject subnet = new JSONObject(subnetsJSON); JSONArray subnetobj = subnet.getJSONArray("subnets"); for (int i = 0; i < subnetobj.length(); i++) { JSONObject objsrv = subnetobj.getJSONObject(i); subnets.setName(objsrv.getString("name")); subnets.setGw(objsrv.getString("gateway_ip")); subnets.setCidr(objsrv.getString("cidr")); subnets.setId(objsrv.getString("id")); HashMap<String, String> map = new HashMap<String, String>(); map.put(NAME, subnets.getName()); map.put(GW, subnets.getGw()); map.put(CIDR, subnets.getCidr()); map.put(ID, subnets.getId()); jsonList.add(map); } } catch (JSONException e) { Log.d("ErrorInitJSON", e.toString()); e.printStackTrace(); } Collections.sort(jsonList, new Comparator<HashMap<String, String>>() { @Override public int compare(HashMap<String, String> lhs, HashMap<String, String> rhs) { return (lhs.get("name")).compareToIgnoreCase(rhs.get("name")); } }); if (mListener != null) { mListener.onJsonLoaded(jsonList); } return jsonList; } } 
+14
java android android-recyclerview
source share
3 answers

You can check if it is empty empty:

 if (adapter.getItemCount() == 0) 

If it does not work, it means that you do not have an override of getItemCount on your adapter! so make sure it is canceled:

 @Override public int getItemCount() { return mDataSet.size(); // Where mDataSet is the list of your items } 

Update: Therefore, based on your update, you can continue. In my opinion, you just need a callback. You are checking for an empty list in onViewCreated. Instead, you should use a callback. Do something like this:

 public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.supportsPredictiveItemAnimations(); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setClickable(true); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); pDialog = new ProgressDialog(getActivity()); pDialog.setMessage("Retrieving data from Server"); pDialog.show(); } 

In the class that you use to populate jsonList, I assume that an asintex or a separate class adds this:

 private OnJsonLoaded mListener; public void setOnJsonLoadedListener(OnJsonLoaded listener) { mListener = listener; } public interface OnJsonLoaded { void onJsonLoaded(ArrayList<HashMap<String, String>> list); } 

now, in asynctask that populate the jsonLise ur or when the json parser completes, call the listener:

 if (mListener != null) { mListener.onJsonLoaded(jsonList); } 

In your fragment (the one with NovaAdapter novaAdapter = new NovaAdapter (getActivity (), jsonList) and your recyclerview) add an implementation of the interface:

 classThatParseJson.setOnJsonLoadedListener(new OnJsonLoaded() { @Override public void onJsonLoaded(ArrayList<HashMap<String, String>> list) { if (list.size() != 0) { NovaAdapter novaAdapter = new NovaAdapter(getActivity(),jsonList); recyclerView.setAdapter(novaAdapter); } else { // Show something like a dialog that the json list is 0 or do whatever you want... here the jsonlist have a count of 0 so it empty! } } }); 

the code may contain errors, I wrote it manually without using the IDE, so maybe you need to fix small things, but the logic is completely clear!

Update based on your update 2:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_subnets, container, false); recyclerView = (RecyclerView)rootView.findViewById(R.id.subnetsRV); return rootView; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.supportsPredictiveItemAnimations(); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setClickable(true); recyclerView.setHasFixedSize(true); recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); // start json parser here instead of passing to fragment as a bundle SubnetsParser.parseJSON(yourparams); } @Override public void onJsonLoaded(ArrayList<HashMap<String, String>> list) { SubnetsParser.setOnJSONLoadedListener(new OnJSONLoaded() { @Override public void onJsonLoaded(ArrayList<HashMap<String, String>> list) { if (list.size() != 0){ SubnetsAdapter subnetsAdapter = new SubnetsAdapter(getActivity(),jsonList); recyclerView.setAdapter(subnetsAdapter); }else { //pDialog = new ProgressDialog(getActivity()); //pDialog.setMessage("Retrieving data from Server"); //pDialog.show(); //Instead of a progressdialog, put here a dialog informing that the list is empty! } } }); } 
+11
source share

As described in https://developer.android.com/training/material/lists-cards.html

The override method getItemCount() is called by the layout manager. This is a snippet:

 // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; } 

So, to find that recyclerView empty, you have to request it on the LayoutManager . Example:

 if( mLayoutManager.getItemCount() == 0 ){ //Do something } 

I am trying to getItemCount() my Adapter , but it returns 0, I don’t know why this is ...

+3
source share

if (adapter.getItemCount () == 0)

doing it worked for me ...

0
source share

All Articles