2014-11-11 14 views
13

मैंने समर्थन लाइब्रेरी v7-21 का उपयोग किया और RecyclerView सही ढंग से प्रदर्शित नहीं हो रहा है। GridLayoutManager और LinearLayoutManager ठीक है। समस्या तब होती है जब StaggeredGridLayoutManager में मैं अपना DataSet लोड करता हूं और फिर डेटा रीफ्रेश करता हूं। डेटा रीफ्रेश ठीक काम कर रहा है लेकिन RecyclerView का दृश्य स्क्रीन से बाहर मौजूद है।पुनर्चक्रण दृश्य, StaggeredGridLayoutManager ताज़ा करें

क्या कोई जानता है कि इसे कैसे ठीक किया जाए?

+1

वही मेरे लिए क्या हो रहा है ... :( StaggeredGridLayoutManager आज के रूप में गाड़ी ... – mato

उत्तर

9

Updated 2015-01-04 (नीचे)

मैं https://github.com/dbleicher/recyclerview-grid-quickreturn पर इस प्रदर्शन करने के लिए एक उदाहरण परियोजना है। लेकिन यहां कुछ और विवरण दिए गए हैं जो आपकी मदद कर सकते हैं।

जब आप रीसाइक्लिंग व्यू में कोई आइटम जोड़ते/हटाते हैं, तो आपको सूचित करना चाहिए ItemInserted/NotifyItem एडाप्टर को लेआउट मैनेजर को केवल प्रभावित दृश्यों को फिर से लेआउट करने के लिए कहा गया है। उदाहरण के लिए, अनुकूलक में:

public void addItemAtPosition(int position, String item) { 
    myDataset.add(position, item); 
    mAdapter.notifyItemInserted(position);   
} 

आप एक दृश्य जोड़ने के लिए इस विधि कहते हैं, और देखने के लिए स्क्रीन पर है, तो SGLM उम्मीद डालने और लेआउट को एडजस्ट करने के रूप में काम करने लगता है। यदि, हालांकि, आप सूची के शीर्ष को देख रहे हैं और आप आइटम को शून्य पर जोड़ते हैं, तो दृश्य ऑफ-स्क्रीन बनाया गया है (और आप इसे नहीं देख पाएंगे)। आप इस निम्न कोड के साथ इस दृश्य के लिए स्क्रॉल कर सकते हैं:

public void addItemAtPosition(int position, String item) { 
    myDataset.add(position, item); 
    mAdapter.notifyItemInserted(position); 
    mSGLM.scrollToPosition(position); 
} 

(IMHO) StaggeredGridLayoutManager में एक बग है कि आइटम "ऑफ स्क्रीन" जोड़ने के साथ पता चला है नहीं है। इस सूत्र https://plus.google.com/u/1/111532428576115387787/posts/6xxayUBz2iV

में Yiğit boyar से टिप्पणी के अनुसार, "... अगर एक आइटम सीमा से बाहर जोड़ा जाता है, लेआउट प्रबंधक परवाह नहीं है"

और यहाँ जहां बग प्रकट होता है। एसजीएलएम के साथ, के साथ एक समय मुद्दा है जब री-लेआउट होता है। मेरे उदाहरण कोड (उपरोक्त लिंक) में मेरे पास एक आइटमडिकोरेटर है जो शीर्ष-वस्तु (आइटम) में मार्जिन जोड़ता है ताकि वे टूलबार द्वारा अस्पष्ट न हों। उपर्युक्त कोड का उपयोग करते समय, लेआउट गलत तरीके से इस मार्जिन को उस आइटम पर बरकरार रखता है जो स्क्रीन को "नीचे" ले जाया जाता है जब नई वस्तुएं डाली जाती हैं। ओह।

यहाँ शीर्ष पर जोड़ने से पहले लेआउट है: Layout before adding at top

यहाँ शीर्ष पर एक आइटम जोड़ने के बाद बग प्रदर्शन लेआउट है: Bad layout

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

public void addItemAtPosition(int position, String item) { 
    myDataset.add(position, item); 
    mAdapter.notifyDataSetChanged(); // Should NOT do this, but it works! 
    mSGLM.scrollToPosition(position); 
} 

उचित, बाद इसके अलावा लेआउट में परिणाम होगा:: Proper layout result

आशा इस मदद करता है निम्नलिखित कोड का उपयोग करना।

अद्यतन: 2014-01-04

टिप्पणी में बताया गया है, एक और वैकल्पिक हल डालने प्रदर्शन के बाद invalidateItemDecorations() recyclerview पर कॉल करने के लिए है। अभी, ऐसा प्रतीत होता है कि सम्मिलन के तुरंत बाद ऐसा करने से इस कॉल को अनदेखा कर दिया जाएगा (संभवतः क्योंकि लेआउट पास पहले से चल रहा है)। एक संक्षिप्त कॉल defers है, यह काम करने के लिए प्रतीत होता है:

public void addItemAtPosition(int position, String item) { 
    myDataset.add(position, item); 
    mAdapter.notifyItemInserted(position); 
    mSGLM.scrollToPosition(position); 

    // Items added to the top row? Better invalidate the decorator. 
    // Delay to ensure that the previous layout pass has completed. 
    if (position < columnCount) { 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mRecycler.invalidateItemDecorations(); 
      } 
     }, 300); 
    } 
} 
+0

मद सजावट के साथ-साथ कैश नहीं किया जाता तो जब तक एक आइटम अवैध है, हम इसे rebind नहीं होगा। आप बुलाना चाहिए ' rv.invalidateItemDecorations'। – yigit

+0

जब मैं आइटम डालने के बाद rv.invalidateItemDecorations() को कॉल करता हूं, तो कॉल को अनदेखा किया जाता है क्योंकि (मुझे विश्वास है) कॉल से प्रगति में पहले से ही एक लेआउट पास है, सूचित करने के लिए ITemInserted। अगर कोई अमान्य करने के लिए कॉल अस्वीकार करता है ITemDecorations (), यह काम करता है। इसलिए, सजावट को अमान्य करने के लिए अभी भी "समय" का एक मुद्दा है। – MojoTosh

0

एक सरल समाधान जो मैंने पाया, फिर लेआउट प्रबंधक स्थापित करने के लिए जब आप अपने recycler को देखने के लिए एडाप्टर सेट है कि आप है।

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