2014-10-29 19 views
34

मैं अपने RecyclerView के लिए खोज कार्यक्षमता को कार्यान्वित करना चाहता हूं। पाठ पर बदल गया मैं इस विजेट के साथ प्रदर्शित डेटा को बदलना चाहता हूं। हो सकता है कि इस सवाल का पहले से पूछा गया है या सरल है, लेकिन मैं नहीं जानता कि कैसे परिवर्तन डेटा है कि दिखाया जा सकता है ...पुनर्चक्रण देखें डेटा सेट

मेरे RecyclerView के रूप में परिभाषित किया गया है इस प्रकार है:

 // 1. get a reference to recyclerView 
    mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView); 

    // 2. set layoutManger 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    // 3. create an adapter 
    mAdapter = new ItemsAdapter(itemsData); 
    // 4. set adapter 
    mRecyclerView.setAdapter(mAdapter); 

और

ItemData itemsData[] = { new ItemData("Mary Richards"), 
     new ItemData("Tom Brown"), 
     new ItemData("Lucy London")   
}; 

तो जब मैं, अनुकूलक डेटा का एक और सेट, (उदाहरण के लिए एक आइटम के साथ) एक और सरणी देना चाहता हूँ कि मैं क्या करना चाहिए जब: डेटा है कि मैं दिखा रहा कुछ की तरह है?

+0

आप आप सिर्फ इसका एक नया 'ItemsAdapter' बना सकते हैं एक और सरणी देना चाहता हूँ और फिर setAdapter' फोन' है। –

उत्तर

74

आप अपने अनुकूलक में स्थिर आईडी है, तो आप बहुत अच्छे परिणाम (एनिमेशन) प्राप्त कर सकते हैं अगर आप फ़िल्टर किए गए आइटम वाले एक नई सरणी बना सकते हैं और फोन

recyclerView.swapAdapter(newAdapter, false); 

swapAdapter संकेत का उपयोग करना है कि यह कर सकते हैं RecyclerView दृश्य धारकों का पुनः उपयोग करें। (सेट एडाप्टर में बनाम, इसे सभी विचारों को रीसायकल करना और फिर से बनाना है क्योंकि यह नहीं पता कि नए एडाप्टर में पुराने एडाप्टर के साथ एक ही व्यूहोल्डर सेट है)।

एक बेहतर तरीका यह पता लगाएगा कि कौन से आइटम हटा दिए गए हैं और notifyItemRemoved(index) पर कॉल कर रहे हैं। वास्तव में आइटम को हटाने के लिए मत भूलना। यह RecyclerView पूर्वानुमानित एनिमेशन चलाएगा। मान लें कि आप एक एडाप्टर है कि आंतरिक रूप से एक ArrayList का उपयोग करता है, कार्यान्वयन इस प्रकार दिखाई देगा:

// adapter code 
final List<ItemData> mItems = new ArrayList(); //contains your items 
public void filterOut(String filter) { 
    final int size = mItems.size(); 
    for(int i = size - 1; i>= 0; i--) { 
     if (mItems.get(i).test(filter) == false) { 
      mItems.remove(i); 
      notifyItemRemoved(i); 
     } 
    } 
} 

यह प्रदर्शन करेंगे, भले ही आप बैच notifyItemRemoved कॉल कर सकते हैं और इसके बजाय notifyItemRangeRemoved का उपयोग बेहतर है। यह sth दिखाई देगा: (परीक्षण नहीं)

public void filterOut(String filter) { 
    final int size = mItems.size(); 
    int batchCount = 0; // continuous # of items that are being removed 
    for(int i = size - 1; i>= 0; i--) { 
     if (mItems.get(i).test(filter) == false) { 
      mItems.remove(i); 
      batchCount ++; 
     } else if (batchCount != 0) { // dispatch batch 
      notifyItemRangeRemoved(i + 1, batchCount); 
      batchCount = 0; 
     } 
    } 
    // notify for remaining 
    if (batchCount != 0) { // dispatch remaining 
     notifyItemRangeRemoved(0, batchCount); 
    } 
} 

आप आइटम है कि पहले बाहर फ़िल्टर किया गया जोड़ने के लिए इस कोड का विस्तार करने की जरूरत है, लेकिन अब दिखाई देना चाहिए (जैसे उपयोगकर्ता फ़िल्टर क्वेरी से हटा देता है) लेकिन मुझे लगता है कि यह एक ऐसा करना चाहिए मूल विचार दें।

ध्यान रखें कि, प्रत्येक सूचित आइटम कॉल इसके बाद प्रभावित करता है (यही कारण है कि मैं इसे से बचने के लिए सूची से आगे बढ़ रहा हूं)। अंत से ट्रैवर्सिंग भी ऐरेलिस्ट के हटाने विधि प्रदर्शन (शिफ्ट करने के लिए कम आइटम) में मदद करता है।

उदाहरण के लिए, यदि आप शुरुआत से सूची को घुमा रहे थे और पहले दो आइटम हटा दिए थे। आप या तो

notifyItemRangeRemoved(0, 2); // 2 items starting from index 0 

या अगर आप उन्हें एक

notifyItemRemoved(0); 
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0 
+0

आपकी प्रतिक्रिया के लिए धन्यवाद, मैं समायोजन करूँगा जो मेरी ज़रूरतों को पूरा करेगा, लेकिन मुझे मूल रूप से इसकी आवश्यकता है। आपने इसे बहुत अच्छी तरह समझाया। – Sandra

+1

"स्थिर आईडी" का क्या अर्थ है? मेरा डेटासेट बदलता है लेकिन मुझे इस तरह से पता नहीं है (कुछ नए आइटम जोड़े जा सकते हैं और कुछ को हटाया जा सकता है) फिर भी दृश्य वही रहता है, तो क्या मुझे स्वैप एडाप्टर के लिए सही या गलत होना चाहिए? –

2

बस अपने अनुकूलक को पुनः आरंभ कर:

mAdapter = नए ItemsAdapter (newItemsData);

या आप केवल बल्कि एक पूरी सूची की तुलना में कुछ विशिष्ट आइटम जोड़ने को दूर करने की जरूरत है:

mAdapter। notifyItemInserted (स्थिति);

या

mAdapter.notiftyItemRemoved (स्थिति);

22

द्वारा एक प्रेषण यह मेरा जवाब है बुलाना चाहिए - उसके साइट से इवान Skoric करने के लिए धन्यवाद: http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/

मैं एक अतिरिक्त विधि बनाया मेरे एडाप्टर वर्ग के अंदर:

public void updateList(List<Data> data) { 
    mData = data; 
    notifyDataSetChanged(); 
} 

फिर प्रत्येक बार वाई हमारा डेटा बदलता है, आप बस इस विधि को अपने नए डेटा में गुजरते हैं और आपका दृश्य इसे प्रतिबिंबित करने के लिए बदलना चाहिए।

+0

सूचित करेंडेटाट चेंज() सभी एनिमेशन को मारता है, केवल बड़ी सूचियों के लिए अच्छा है। – Davidea

+0

@Davidea ... जो रीसाइक्लर व्यू –

+0

का सामान्य उपयोग केस है, एक रीसाइक्लिंगव्यू केवल आपके दृश्य दृश्यों को स्मृति में रखता है और जब आप उन्हें अपनी स्क्रीन से स्क्रॉल करते हैं तो उन्हें छोड़ दें। यह एक सूचीदृश्य की तुलना में एक स्मृति परिप्रेक्ष्य से अत्यधिक कुशल है। वे एक सूचीदृश्य के समान काम करते हैं। आप यहां रीसाइक्लिंग व्यू दस्तावेज़ पढ़ सकते हैं: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html – Simon

0

ygit उत्तर दिया गया, swapAdapter जब आप पूरी सामग्री को बदलना चाहते हैं तो दिलचस्प है।

लेकिन, मेरे फ्लेक्सिबल एडाप्टर में, आप updateDataSet के साथ आइटम अपडेट कर सकते हैं। आप एडाप्टर को notifyDataSetChanged पर कॉल करने या सिंक्रनाइज़ेशन एनिमेशन (डिफ़ॉल्ट रूप से सक्षम) को कॉन्फ़िगर करने के लिए भी कॉन्फ़िगर कर सकते हैं। यह, क्योंकि सूचित करेंडेटाट चेंज ने सभी एनिमेशन को मार दिया, लेकिन बड़ी सूचियों के लिए यह अच्छा है।

कृपया विवरण पर एक नजर है, demoApp और विकी पृष्ठों: https://github.com/davideas/FlexibleAdapter

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