2014-07-09 8 views
8

Activity से Fragment पर कॉल करके, मैं ListView को दो Buttons के साथ प्रदर्शित कर रहा हूं। जब मैं menu_item (यानी ऑनलाइन दिखाएं) पर क्लिक करता हूं, तो मैं डेटा अपडेट कर रहा हूं और इसलिए ListView। अब मुझे अद्यतन डेटा को प्रतिबिंबित करने की आवश्यकता है। ऑनलाइन दिखाएँ क्लिक करने के बाद मैं Fragment को रीफ्रेश कैसे कर सकता हूं। अब तक, मैं निम्नलिखित कोड का इस्तेमाल किया है:एक ही गतिविधि में शेष वर्तमान फ्रैगमेंट (सूची दृश्य डेटा) को रीफ्रेश करें

Intent intent = getIntent(); 
Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
finish(); 
startActivity(intent); 

लेकिन इस पूरे Activity पुनः आरंभ करेगा। मुझे बस वर्तमान Fragment रीफ्रेश करने की आवश्यकता है।

enter image description here enter image description here

संपादित: कोड जोड़ा गया

गतिविधि कक्षा

public class ContactListActivity extends ActionBarActivity { 

    ListView listView; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     final ActionBar actionBar = getActionBar(); 
     MenuButtonUtil.enableMenuButton(this); 

     FragmentManager fragmentManager = getFragmentManager(); 

     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

     MyContactsFragment contactListFragment = new MyContactsFragment(); 
     fragmentTransaction.replace(android.R.id.content, contactListFragment); 
     fragmentTransaction.commit(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == R.id.show_online) { 
      ContentValues values = new ContentValues(); 
      String where = "((" + ContactsContentProvider.PHONE_ID + " NOTNULL) AND ((" + 
         ContactsContentProvider.PHONE_ID+ " = 17486)OR (" + 
         ContactsContentProvider.PHONE_ID+ " = 17494)))"; 

      values.put(ContactsContentProvider.STATUS, true); 
      this.getContentResolver().update(ContactsContentProvider.CONTENT_URI, values, where, null); 

      listView = (ListView) this.findViewById(android.R.id.list); 
      ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged(); 

      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

} 

टुकड़ा

public class MyContactsFragment extends ListFragment{ 

Button allContactsBtn; 
Button neeoContactsBtn; 
ListView listView; 
CustomAdapterForAllContacts adapterForAllContacts; 
CustomAdapterForNeeoContacts adapterForNeeoContacts; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    final ActionBar actionBar = getActivity().getActionBar(); 
    MenuButtonUtil.enableMenuButton(getActivity()); 
    adapterForNeeoContacts = new CustomAdapterForNeeoContacts(); 
    adapterForAllContacts = new CustomAdapterForAllContacts(); 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 

    View view = inflater.inflate(R.layout.contactsfragment, container,false); 

    allContactsBtn = (Button) view.findViewById(R.id.allContactsButton); 
    neeoContactsBtn = (Button) view.findViewById(R.id.neeoContactsButton); 
    listView = (ListView) view.findViewById(android.R.id.list); 


    // ==================== Neeo Contacts ============================ 
    neeoContactsBtn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listView.setAdapter(adapterForNeeoContacts); 

     } 
    }); 

    // ====================== All Contacts ============================= 

    allContactsBtn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      listView.setAdapter(adapterForAllContacts); 
     } 
    }); 

    return view; 
} 

एडाप्टर:

private class CustomAdapterForAllContacts extends BaseAdapter { 

public CustomAdapterForAllContacts(){ 

} 
    List<Contact> contactsList = getAllContacts(); 
    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return contactsList.size(); 
    } 

    @Override 
    public Contact getItem(int arg0) { 
     // TODO Auto-generated method stub 
     return contactsList.get(arg0); 
    } 

    @Override 
    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return arg0; 
    } 

    @Override 
    public View getView(int position, View view, ViewGroup viewGroup) { 

     if(view==null) 
     { 
      LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      view = inflater.inflate(R.layout.list_item, viewGroup,false); 
     } 

     TextView contName = (TextView)view.findViewById(R.id.nameText); 
     TextView contNumber = (TextView)view.findViewById(R.id.numberText); 
     ImageView image = (ImageView)view.findViewById(R.id.contact_image); 

     Contact contact = contactsList.get(position); 

     String status = contact.getStatus(); 

     if(contact.getStatus().equals("1")){ 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); 
     }else{ 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); 
     } 

     contName.setText(contact.getName()); 
     contNumber.setText(contact.getPhoneNumber()); 
     return view; 
    } 

    public Contact getContactPosition(int position) 
    { 
     return contactsList.get(position); 
    } 
    public List<Contact> getAllContacts(){ 

     List<Contact> contactList = new ArrayList<Contact>(); 

     String URL = "content://com.example.provider.Contacts/contacts"; 
     Uri baseUri1 = Uri.parse(URL); 
     String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; 

     String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + 
                ContactsContentProvider.NEEO_USER+ " = 1)AND (" + 
                ContactsContentProvider.STATUS+ " = 1))"; 

     Cursor cursor = getActivity().getContentResolver().query(baseUri1, select, where, null, "pid"); 

     for(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { 
      Log.w("Filtered IDS",""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID))+ 
        ""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
     } 


     Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; 

     String[] projection = new String[] { 
       ContactsContract.CommonDataKinds.Phone._ID, 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
       ContactsContract.CommonDataKinds.Phone.NUMBER}; 

     String selection = "((" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' '))"; 

     String[] selectionArgs = null; 
     String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; 

     Cursor mCursor= getActivity().getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); 

     // Joinging Both Cursors 
       CursorJoiner joiner = new CursorJoiner(cursor, new String[] {ContactsContentProvider.PHONE_ID} , mCursor, new String[] {ContactsContract.CommonDataKinds.Phone._ID}); 
       for (CursorJoiner.Result joinerResult : joiner) { 
        Contact cont = new Contact(); 
        Log.e("Result", joinerResult.toString()); 
        switch (joinerResult) { 
        case LEFT: 
         // handle case where a row in cursorA is unique 
         break; 
        case RIGHT: 
         // handle case where a row in cursorB is unique 
         cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
         cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
         cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
         cont.setStatus("0"); 
         contactList.add(cont); 
         break; 
        case BOTH: 
         // handle case where a row with the same key is in both cursors 
         cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
         cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
         cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
         cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
         contactList.add(cont); 
         break; 
        } 
       } 
       mCursor.close(); 
       cursor.close(); 
     return contactList; 
    } 
} 
+0

उस के लिए 'ListFragment' प्रयुक्त ... –

+0

फिर क्या? फ्रैगमेंट को ताज़ा करने के बारे में ListFragment के बारे में कोई विशिष्ट बात। –

+0

और उस एडाप्टर पर 'notifyDataSetChanged() 'गतिविधि' Resume()' या कहीं भी ... यह आपके 'ListFragment' को अपडेट करेगा ... –

उत्तर

14

आप कैसे वास्तव में आप अपने ListView और Adapter कार्यान्वित के आधार पर इस समस्या के समाधान के लिए कई विकल्प हैं कर सकते हैं।

  1. notifyDataSetChanged()
  2. बुला notifyDataSetChanged() के साथ Adapter

अद्यतन कर रहा है को रीसेट द्वारा

यह सबसे अच्छा समाधान वहाँ है, लेकिन आप List संशोधित करने की आवश्यकता Adapter इस काम के लिए उपयोग कर रहा है। उदाहरण के लिए यदि आप एक ArrayAdapter इस तरह का उपयोग करें:

String[] dataSource = new String[] { 
    "A", "B", "C", ... 
}; 

ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, dataSource); 

आप देख सकते हैं String[] हमारे Adapter के लिए डेटा स्रोत है।हम इस तरह सरणी संशोधित कर सकते हैं, लेकिन वे परिवर्तन तुरंत ListView में परिलक्षित नहीं किया जाएगा:

dataSource[0] = "some new String value"; 

केवल एक बार हम notifyDataSetChanged()ListView अद्यतन किया जाएगा फोन:

adapter.notifyDataSetChanged(); 

documentation से:

सार्वजनिक शून्य अधिसूचनाडेटासेट चेंज()

संलग्न पर्यवेक्षकों को सूचित करता है कि अंतर्निहित डेटा बदल गया है और डेटा सेट को प्रतिबिंबित करने वाले किसी भी दृश्य को स्वयं को ताज़ा करना चाहिए।

लेकिन , क्या नहींnotifyDataSetInvalidated() साथ notifyDataSetChanged() भ्रमित क्योंकि notifyDataSetInvalidated() कुछ पूरी तरह से अलग करता है और होगा अपने ListView सिर्फ गंदगी।

documentation से:

सार्वजनिक शून्य notifyDataSetInvalidated()

सूचना देता संलग्न पर्यवेक्षकों कि अंतर्निहित डेटा नहीं रह गया है वैध या उपलब्ध है। एक बार यह एडाप्टर लागू करने के बाद मान्य नहीं है और को और डेटा सेट परिवर्तनों की रिपोर्ट नहीं करनी चाहिए।


अद्यतन कर रहा है Adapter

यह रीसेट करके सुंदर सीधे आगे है। प्रत्येक बार जब आप एक नया Adapter सेट करते हैं तो ListView स्वयं अपडेट हो जाएगा। यदि आप किसी कारण से notifyDataSetChanged() का उपयोग नहीं कर सकते हैं तो आपको इसे ऐसा करना होगा।

ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, newData); 

और ListViewsetAdapter() उपयोग करने के लिए यह निर्धारित करने के लिए:: बस एक नया Adapter हर बार अपना ListView अपडेट करना चाहते हैं बनाने

listView.setAdapter(adapter); 

यह हमेशा ListView अपडेट करेगा, लेकिन कुछ समस्याएं हैं इस समाधान के साथ। सबसे पहले और सबसे महत्वपूर्ण जब आप ListView को अपडेट करते हैं, तो यह शीर्ष पर वापस स्क्रॉल करेगा जो अक्सर अद्यतन होने पर या ListView में बहुत सारी सामग्री होने पर काफी परेशान हो सकता है।


संपादित करें:

वहाँ अपने कोड में कुछ चीजें हैं जो काफी इष्टतम नहीं हैं। सबसे पहले और सबसे महत्वपूर्ण, आपके Adapter में संपर्क डाउनलोड करने के लिए कोड नहीं होना चाहिए। यह सिर्फ वहां नहीं है, Adapter की एकमात्र ज़िम्मेदारी यह होनी चाहिए कि वह किसी दिए गए डेटा स्रोत से Views बनाता है।तो सबसे पहले आपको विधि Adapter के बाहर ले जाना चाहिए। मेरा सुझाव है कि आप इस के लिए स्थिर सहायक विधि बनाने के लिए, मैं उसके अनुसार अपनी कोड को संशोधित करने की स्वतंत्रता ले लिया:

List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); 

इस के बाद हम की जरूरत है:

public class ContactsHelper { 

    public static List<Contact> getAllContacts(Context context) { 

     List<Contact> contactList = new ArrayList<Contact>(); 

     String URL = "content://com.example.provider.Contacts/contacts"; 
     Uri baseUri1 = Uri.parse(URL); 
     String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; 

     String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + 
       ContactsContentProvider.NEEO_USER + " = 1)AND (" + 
       ContactsContentProvider.STATUS + " = 1))"; 

     Cursor cursor = context.getContentResolver().query(baseUri1, select, where, null, "pid"); 

     for (cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { 
      Log.w("Filtered IDS", "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID)) + 
        "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
     } 

     Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; 

     String[] projection = new String[]{ 
       ContactsContract.CommonDataKinds.Phone._ID, 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, 
       ContactsContract.CommonDataKinds.Phone.NUMBER}; 

     String selection = "((" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + 
       ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' '))"; 

     String[] selectionArgs = null; 
     String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; 

     Cursor mCursor = context.getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); 

     // Joinging Both Cursors 
     CursorJoiner joiner = new CursorJoiner(cursor, new String[]{ContactsContentProvider.PHONE_ID}, mCursor, new String[]{ContactsContract.CommonDataKinds.Phone._ID}); 
     for (CursorJoiner.Result joinerResult : joiner) { 
      Contact cont = new Contact(); 
      Log.e("Result", joinerResult.toString()); 
      switch (joinerResult) { 
       case LEFT: 
        // handle case where a row in cursorA is unique 
        break; 
       case RIGHT: 
        // handle case where a row in cursorB is unique 
        cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
        cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
        cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
        cont.setStatus("0"); 
        contactList.add(cont); 
        break; 
       case BOTH: 
        // handle case where a row with the same key is in both cursors 
        cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); 
        cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); 
        cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
        cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); 
        contactList.add(cont); 
        break; 
      } 
     } 
     mCursor.close(); 
     cursor.close(); 
     return contactList; 
    } 
} 

इस कोड के साथ आप इस तरह सभी संपर्कों को प्राप्त कर सकते हैं संशोधित अपने Adapter ताकि notifyDateSetChanged() काम करेगा:

private class CustomAdapterForAllContacts extends BaseAdapter { 

    private final List<Contact> contactsList; 
    private final LayoutInflater inflater; 

    public CustomAdapterForAllContacts(Context context, List<Contact> contacts) { 
     this.inflater = LayoutInflater.from(context); 
     this.contactsList = contacts; 
    } 

    @Override 
    public int getCount() { 
     return contactsList.size(); 
    } 

    @Override 
    public Contact getItem(int position) { 
     return contactsList.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    // We expose the List so we can modify it from outside 
    public List<Contact> contacts() { 
     return this.contactsList;  
    } 

    private class SimpleViewHolder { 

     private final SparseArray<View> viewArray = new SparseArray<View>(); 
     private final View convertView; 

     public SimpleViewHolder(View convertView) { 
      this.convertView = convertView; 
     } 

     public View get(int id) { 
      View view = this.viewArray.get(id, null); 
      if(view == null) { 
       view = this.convertView.findViewById(id); 
       this.viewArray.put(id, view); 
      } 
      return view; 
     } 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup viewGroup) { 

     // By implementing the view holder pattern you only need to perform 
     // findViewById() once. This will improve the performance of `ListView` 
     // and reduce lag. 
     SimpleViewHolder viewHolder; 
     if (convertView == null) { 
      convertView = this.inflater.inflate(R.layout.list_item, viewGroup, false); 
      viewHolder = new SimpleViewHolder(convertView); 
      convertView.setTag(viewHolder); 
     } 

     viewHolder = (SimpleViewHolder) convertView.getTag(); 

     TextView contName = (TextView) viewHolder.get(R.id.nameText); 
     TextView contNumber = (TextView) viewHolder.get(R.id.numberText); 
     ImageView image = (ImageView) viewHolder.get(R.id.contact_image); 

     Contact contact = getItem(position); 

     String status = contact.getStatus(); 

     if (contact.getStatus().equals("1")) { 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); 
     } else { 
      image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); 
     } 

     contName.setText(contact.getName()); 
     contNumber.setText(contact.getPhoneNumber()); 
     return view; 
    } 
} 

मैं इस Adapter में कई चीजें बदल गई। सबसे पहले और सबसे महत्वपूर्ण ListContacts अब अंतिम है और मैंने List का पर्दाफाश करने के लिए contacts() विधि जोड़ा है ताकि हम बाहर से Adapter में डेटा को संशोधित कर सकें। मैंने व्यू धारक पैटर्न भी लागू किया है ताकि आपके ListView स्क्रॉल तेज़ और चिकनी हो जाएं!

मुझे आशा है कि मैं कुछ भी नहीं भूल गया हूं, लेकिन यह आपके लिए आवश्यक सभी परिवर्तन होना चाहिए। आप नए Adapter इस तरह उपयोग कर सकते हैं:

List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); 
CustomAdapterForAllContacts adapter = new CustomAdapterForAllContacts(getActivity(), contacts); 
listView.setAdapter(adapter); 

आप बाद में ListView अद्यतन करने के लिए आप Adapter इस तरह अंदर List संशोधित करने की आवश्यकता पर चाहते हैं:

List<Contact> newData = ContactsHelper.getAllContacts(getActivity()); 
adapter.contacts().clear(); 
adapter.contacts().addAll(newData); 
adapter.notifyDataSetChanged(); 

मुझे आशा है कि मैं आपकी मदद कर सकता है और यदि आपके कोई और प्रश्न हैं तो कृपया बेझिझक पूछें!

+0

मेरा संपादित प्रश्न देखें। –

+0

मैंने कोड भी शामिल किया है। अब जांचें। –

+1

ठीक है, मैं देखता हूं। आपको एडाप्टर के अंदर डेटा का डाउनलोड नहीं करना चाहिए। ऐसा कुछ नहीं है। 'एडाप्टर 'के अंदर डेटा स्रोत के रूप में उपयोग की जाने वाली' सूची 'सामान्य रूप से अंतिम होनी चाहिए और आपके जैसा नहीं किया जाना चाहिए। मैं कुछ सुझावों के साथ अपना जवाब संपादित करूंगा। –

1

आप एक टुकड़ा अंदर हैं तो आप

// code for fetching the data 
// ... 
// ... 
((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged(); 
संबंधित मुद्दे