2014-12-01 9 views
7

मेरे पास एक सर्वर से पार्स किए गए बाहरी JSON डेटा प्राप्त करने वाला एक RecyclerView है। यह ठीक काम करता है हालांकि JSON पर वॉली एसिंक कार्य में कुछ समय लगता है और जब यह खंड खाली खाली दृश्य प्रदर्शित करता है।रीसाइक्लर व्यू खाली होने पर कैसे पता लगाया जाए?

यह देखने के लिए कि मैं दृश्य खाली है या नहीं, एक संदेश कैसे प्रदर्शित कर सकता हूं? मैं जाँच करने की कोशिश की:

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

लेकिन उन परीक्षणों या तो न कुछ भी करने या वे त्रुटि संदेश हर बार भले ही RecyclerView खाली नहीं है प्रदर्शित करते हैं।

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); 

और एडाप्टर पर विधि:

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

जिस तरह से यह अब है प्रगति हमेशा संवाद कोई बात नहीं चलाते हैं दृश्य खाली है

यह टुकड़ा पर कोड है या नहीं।

अद्यतन:

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::

मैं एक वर्ग है जो काफी अब एक कॉलबैक इंटरफ़ेस तथापि 1 सेकंड के लिए recyclerView प्रदर्शित करता है के साथ ऊपर से एक के रूप में ही है अद्यतन यहाँ एडाप्टर कोड है और फिर खाली हो जाता है। संवाद भी नहीं दिखाता है। कोड यह रहा:

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); 
    } 
} 

और यह JSON पार्सर वर्ग है:

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; 

    } 


} 
+0

क्यों एक प्रगति बार नहीं दिखाते ?? Asynctask के साथ एक बहुत ही आम उपयोग है। – Mike

+0

मैं वॉली के साथ प्रोग्रेसबार का उपयोग कैसे कर सकता हूं? जिस तरीके से मेरा ऐप कॉन्फ़िगर किया गया है, वह बैकग्राउंड क्लास में उपयोग किया जाता है जिसे एक खंड – GITcommitEd

+0

रीसाइक्लर व्यू वास्तव में एक 'व्यू ग्रुप' कहा जाता है, क्या आपने कभी "RecyclerView.getChildCount() == 0" कोशिश की है? – VinceStyling

उत्तर

7

आप देख सकते हैं यदि वह रिक्त हो चलाकर:

if (adapter.getItemCount() == 0) 

यह काम नहीं कर रहा यदि आपने इसका मतलब है अपने एडाप्टर पर getItemCount ओवरराइड नहीं करें! इतना यकीन है कि यह overrided है बनाने:

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

अद्यतन: तो अपने अद्यतन के आधार पर यह आप कैसे आगे बढ़ना सकता है। मेरी राय में आपको केवल कॉलबैक की आवश्यकता है। आप जांच रहे हैं कि आपकी ऑनव्यूटेड पर सूची खाली है या नहीं। आपको, कॉलबैक का उपयोग करना चाहिए। ऐसा ही कुछ कार्य करें: अब

private OnJsonLoaded mListener; 

public void setOnJsonLoadedListener(OnJsonLoaded listener) { 
    mListener = listener; 
} 

public interface OnJsonLoaded { 
    void onJsonLoaded(ArrayList<HashMap<String, String>> list); 
} 

, asynctask कि उर jsonLise पॉप्युलेट में:

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(); 
} 

वर्ग आप अपने jsonList पॉप्युलेट करने के लिए उपयोग कर रहे हैं, मैं एक asynctask या एक अलग वर्ग में जोड़ना मान या जब JSON पार्सर अपनी नौकरी खत्म, श्रोता फोन:

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

अपने टुकड़ा (novaAdapter novaAdapter = नए novaAdapter (getActivity(), jsonList) के साथ एक में, और अपने recyclervi आईडीई का उपयोग कर तो हो सकता है आप छोटी बातों को ठीक करने के लिए है, लेकिन तर्क काफी स्पष्ट है बिना

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's empty! 
      } 
     } 
}); 

कोड सकता है containts त्रुटियों, मैं इसे हाथ से लिखा: ew) इंटरफेस कार्यान्वयन जोड़ने!

अद्यतन अपने अद्यतन 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! 
      } 
     } 
    }); 

} 
+0

मैंने कोशिश की लेकिन मुझे मिल गया: java.lang.NullPointerException: ऐप पर एक शून्य ऑब्जेक्ट संदर्भ पर आभासी विधि 'int java.util.ArrayList.size()' को आज़माने का प्रयास करें। इंस्टॉलेशन। नोवाएडाप्टर.getItemCount – GITcommitEd

+0

इस प्रकार विधि पहले थी: @ ओवरराइड सार्वजनिक int getItemCount() { वापसी (शून्य! = नोवालिस्ट? novaList.size(): 0); } – GITcommitEd

+0

तो इसे छोड़ दें क्योंकि यह @Override सार्वजनिक int getItemCount() {वापसी (शून्य! = नोवालिस्ट? NovaList.size(): 0) से पहले था; मुझे अपना पूर्ण स्रोत एडाप्टर दिखाएं व्यूहोल्डरक्रेटेड भाग – iGio90

3

में https://developer.android.com/training/material/lists-cards.html

ओवरराइड विधि getItemCount() लेआउट प्रबंधक द्वारा उत्पन्न होता है वर्णन किया गया है कैसे। यह टुकड़ा है: अगर recyclerView खाली आप अपने LayoutManager को यह अनुरोध करना होगा है

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

तो पता लगाने के लिए। उदाहरण:

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

मैं अपने Adapter की getItemCount() करने की कोशिश, लेकिन यह रिटर्न 0, मैं नहीं जानता कि क्यों यह है ...

संबंधित मुद्दे