2016-01-29 12 views
6

मैं की मेरी RecyclerView रों GridLayoutManager परिवर्तन चेतन करना चाहते हैं के परिवर्तन चेतन। मैं डिफ़ॉल्ट रूप से 3 कॉलम वाले ग्रिड में आइटम्स की एक सूची दिखाता हूं और उपयोगकर्ता अधिक या कम कॉलम दिखाने के लिए चुन सकता है।RecyclerView - ग्रिड लेआउट प्रबंधक कॉलम

मुझे RecyclerView में अपनी नई स्थिति में स्थानांतरित करने/स्केल करने के लिए, लेकिन मुझे नहीं पता कि यह कैसे किया जा सकता है।

क्या मैं अंत में चाहते

  • एक विस्तृत/अनुबंध स्पर्श जेस्चर के माध्यम से ग्रिड पैमाने पर करने के लिए अनुमति देते हैं => मुझे पता है कि कि
  • LayoutManager
के परिवर्तन चेतन करने के लिए

किसी को भी पता है कि कैसे मैं LayoutManager के परिवर्तन चेतन कर सकते हैं?

+0

आप में एक ऐसी ही [सवाल] दिखाई दे सकता है (http://stackoverflow.com/questions/26539663/how-do-i-use-a-gridlayoutanimation-in-a-recyclerview) और संबंधित [ gist] (https://gist.github.com/Musenkishi/8df1ab549857756098ba) – Droidekas

+0

फिर 'setSpanCount' को कॉल करके 'नोटिफ़ाडेटाडेटेड()'? – Droidekas

+0

एक और तरीका यह है कि मैं इसे देख सकता हूं, एक बहुत ही उच्च अवधि गणना (100 या उससे अधिक) और आइटम इशारा पर निर्भर करता है, आप सभी वस्तुओं के लिए अवधि आकार बदल सकते हैं – Droidekas

उत्तर

11

प्रेरणा का स्रोत यहाँ Google फ़ोटो एप्लिकेशन, शेयर सोनी गैलरी ऐप होगा

वहाँ मूलतः हैं 2 दृष्टिकोण आप के साथ जा सकते हैं:

  1. आप का उपयोग GridLayoutManager की spancount संशोधित setSpanCount(int)

  2. आपने फ्लाई पर प्रति आइटम स्पैन आकार बदलने के लिए SpanSizeLookUp का उपयोग करके बहुत अधिक अवधि की गणना (~ 100) सेट की है।

    • मैं Gist Musenkishi द्वारा प्रदान का इस्तेमाल किया है, this answer ग्रिड लेआउट में परिवर्तन चेतन करने के लिए एक एनिमेटर प्रदान करने के लिए बदल जाता है
    • मैं एक sample GitHub project में इस दृष्टिकोण एक ही लागू करने का इस्तेमाल किया है।
    • चेतावनियां:
      • मैं वर्तमान में क्लिक श्रोता का इस्तेमाल किया है अवधि आकार नज़र up.This संशोधित रखने के लिए एक ItemGestureListener को बदला जा सकता है चुटकी ज़ूम घटनाओं पर कब्जा है और उसके अनुसार बदलने के लिए।
      • आप अंतराल गिनती चयन करने के लिए एक तरह से निर्धारित करने के लिए की जरूरत है ताकि एक पंक्ति में सभी आइटम पूरे स्क्रीन चौड़ाई पर कब्जा notifyItemRangeChanged (और इसलिए आप किसी भी खाली जगह नहीं दिख रहा है)
      • आप कॉल एक runnable के बाद से देरी के बाद का उपयोग कर आप bindView/createView आदि के भीतर से सूचित किए गए तरीकों को कॉल नहीं कर सकते हैं।
      • अवधि आकार बदलने के बाद, आप notifyItemRangeChanged के लिए एक उपयुक्त सीमा के साथ इतना है कि सभी वस्तुओं वर्तमान में स्क्रीन accordingly.I स्थानांतरित कर रहे पर प्रदर्शित की जरूरत है (नीचे कोड)
का इस्तेमाल किया है

यह एक पूर्ण समाधान नहीं है लेकिन इसके लिए 2 घंटे का समाधान है। आप स्पष्ट रूप से उल्लिखित सभी बिंदुओं पर सुधार कर सकते हैं :)। मुझे नमूना अपडेट करना जारी रखने की उम्मीद है क्योंकि इस तरह के विचारों ने मुझे हमेशा प्रभावित किया है। इसे अंतिम समाधान के रूप में न देखें बल्कि इस दृष्टिकोण को प्राप्त करने का एक विशेष तरीका है। यदि आप इसके बजाय StaggerredLayoutManager का उपयोग करना चाहते थे, तो आप आसानी से वस्तुओं के बीच खाली रिक्त स्थान से बच सकते हैं।

public int calculateRange() { 
    int start = ((GridLayoutManager)  grv.getLayoutManager()).findFirstVisibleItemPosition(); 
    int end = ((GridLayoutManager) grv.getLayoutManager()).findLastVisibleItemPosition(); 
    if (start < 0) 
     start = 0; 
    if (end < 0) 
     end = getItemCount(); 
    return end - start; 
    } 
+1

इसके लिए धन्यवाद (मैंने सोचा से कहीं ज्यादा आसान) समाधान। अवधि गणना को बदलना (मैं खुद के बारे में सोचा था) आईएमएचओ जाने का तरीका है। यह बहुत अच्छा एनिमेट करता है। और इसे बदलने के बाद बस एडाप्टर को सूचित करें 'सूचित करें ItemRangeChanged' एनीमेशन सही ढंग से शुरू करेगा ... केवल दोष है (लेकिन मैंने अपने प्रश्न में और अधिक नहीं पूछा), आपको केवल' GridLayoutManager' का उपयोग करना होगा और बीच में स्विच नहीं करना चाहिए अलग-अलग 'लेआउट प्रबंधक' ... हालांकि, यदि आप चाहते हैं, तो 'GridLayoutManager' 1 कॉलम का भी समर्थन करता है और इसलिए कम से कम' LinearLayoutManager' के रूप में भी उपयोग किया जा सकता है ... – prom85

+1

यदि आप वास्तव में बाहर निकलना चाहते हैं एनिमेशन और एकल कॉलम लेआउट के प्रदर्शन को बेहतर बनाने के लिए, मैं अपने स्वयं के लेआउट प्रबंधक बनाने पर काम करने की सलाह दूंगा: [यह] (http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/) गाइड बहुत अच्छा है। – Droidekas

+0

@Droidekas क्या आप एंड्रॉइड 7 त्वरित सेटिंग्स पर उस एनीमेशन को बनाने में मेरी मदद कर सकते हैं? (जब आप छाया का विस्तार करते हैं तो त्वरित टाइल्स के साथ होता है - वे आइटम की एक पंक्ति में होते हैं और फिर वे 3x3 के ग्रिड में विस्तार करते हैं।) –

1

मैं तुम्हें रूप में एक ही समस्या से निपटने के लिए, और अब तक मैं एक अच्छा समाधान नहीं मिली है। GridLayoutManager में कॉलम संख्या के

सरल परिवर्तन अजीब तो अब के लिए मैं एनीमेशन का उपयोग बाहर फीका करने के लिए/पूरे लेआउट में लगता है। कुछ इस तरह:

private void animateRecyclerLayoutChange(final int layoutSpanCount) { 
    Animation fadeOut = new AlphaAnimation(1, 0); 
    fadeOut.setInterpolator(new DecelerateInterpolator()); 
    fadeOut.setDuration(400); 
    fadeOut.setAnimationListener(new Animation.AnimationListener() { 
     @Override 
     public void onAnimationStart(Animation animation) { 
     } 

     @Override 
     public void onAnimationRepeat(Animation animation) { 
     } 

     @Override 
     public void onAnimationEnd(Animation animation) { 
      productsRecyclerLayoutManager.setSpanCount(layoutSpanCount); 
      productsRecyclerLayoutManager.requestLayout(); 
      Animation fadeIn = new AlphaAnimation(0, 1); 
      fadeIn.setInterpolator(new AccelerateInterpolator()); 
      fadeIn.setDuration(400); 
      productsRecycler.startAnimation(fadeIn); 
     } 
    }); 
    productsRecycler.startAnimation(fadeOut); 
} 

आप प्रत्येक दिखाई आइटम स्केलिंग के साथ बाहर फीका/एनीमेशन में जोड़ देते हैं तो यह GridLayoutManager परिवर्तन के लिए एक सभ्य एनीमेशन हो जाएगा।

+0

मेरे पास वर्तमान में एक समान समाधान है ... सभी वस्तुओं को हटाकर, बदलना लेआउट मैनेजर और सभी वस्तुओं को वापस जोड़ने के परिणामस्वरूप एनीमेशन भी होगा, लेकिन यह सही नहीं है ... हालांकि इस विकल्प के लिए धन्यवाद। – prom85

1

आप "इशारा डिटेक्टर" साथ ऐसा कर सकते यहाँ http://wiki.workassis.com/pinch-zoom-in-recycler-view/ इस ट्यूटोरियल में देख नमूना ट्यूटोरियल हम गैलरी से छवियों को लाने और उन्हें recycler ध्यान में रखते हुए एक ग्रिड लेआउट में दिखाई देंगे। आप चुटकी इशारा पर लेआउट बदलने में सक्षम हो जाएगा। विभिन्न लेआउट के स्क्रीन शॉट्स निम्नलिखित हैं।

mScaleGestureDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() { 
       @Override 
       public boolean onScale(ScaleGestureDetector detector) { 
        if (detector.getCurrentSpan() > 200 && detector.getTimeDelta() > 200) { 
         if (detector.getCurrentSpan() - detector.getPreviousSpan() < -1) { 
          if (mCurrentLayoutManager == mGridLayoutManager1) { 
           mCurrentLayoutManager = mGridLayoutManager2; 
           mRvPhotos.setLayoutManager(mGridLayoutManager2); 
           return true; 
          } else if (mCurrentLayoutManager == mGridLayoutManager2) { 
           mCurrentLayoutManager = mGridLayoutManager3; 
           mRvPhotos.setLayoutManager(mGridLayoutManager3); 
           return true; 
          } 
         } else if(detector.getCurrentSpan() - detector.getPreviousSpan() > 1) { 
          if (mCurrentLayoutManager == mGridLayoutManager3) { 
           mCurrentLayoutManager = mGridLayoutManager2; 
           mRvPhotos.setLayoutManager(mGridLayoutManager2); 
           return true; 
          } else if (mCurrentLayoutManager == mGridLayoutManager2) { 
           mCurrentLayoutManager = mGridLayoutManager1; 
           mRvPhotos.setLayoutManager(mGridLayoutManager1); 
           return true; 
          } 
         } 
        } 
        return false; 
       } 
      }); 
संबंधित मुद्दे