2012-08-27 19 views
6

का उपयोग करता है, मैं एक ViewPager को कार्यान्वित करना चाहता हूं जो टुकड़ों का उपयोग करता है और एक कर्कुलर गति में स्वाइप किया जा सकता है उदा। पृष्ठ (ए < -> बी < -> सी < -> ए)। मैंने यह कैसे किया है इस पर कुछ पोस्ट पढ़ी हैं, उदाहरण के लिए नकली गिनती लौट रही है कि कितने तत्व हैं और बीच में शुरुआत में स्थिति निर्धारित करते हैं। how to create circular viewpager?सर्कुलर व्यूपेगर जो FragmentPagerAdapter

ये सभी एक पेजर एडाप्टर के आधार पर प्रतीत होते हैं। जब मैं FragmentPagerAdapter को विस्तारित करते समय भी ऐसा ही करने की कोशिश करता हूं, जैसे ही मैं पृष्ठों की नकली गणना देता हूं, मुझे अपवाद मिलता है जब मैं अपने टुकड़ों के माध्यम से स्वाइप करता हूं, मेरे पास केवल 2 टुकड़े होते हैं। अपवाद: java.lang.IllegalStateException: खंड के टैग को नहीं बदला जा सकता है।

मुझे लगता है कि ऐसा इसलिए होता है क्योंकि FragmentManager सोचता है कि मैं स्थिति 2 में हूं लेकिन स्थिति 0 पर टुकड़े के लिए 2 अंक की स्थिति है। क्या कोई जानता है कि मैं इससे कैसे बच सकता हूं? मैं सोच रहा हूं कि मुझे Fragmentmanager को विस्तारित करने के साथ प्रयोग करना चाहिए। इसके साथ किसी भी उदाहरण या मदद की सराहना की जाएगी।

+0

मैं इस के लिए एक समाधान को क्रियान्वित किया है मदद की। मैं परीक्षणों को लगभग पूरा कर रहा हूं और जब मैं कर रहा हूं तो मैं यहां जवाब दूंगा। –

+0

@FernandoCamargo क्या आपने इसे हल किया है ?? –

+0

हाँ। मुझे खेद है, मैं इसे यहां जवाब देना भूल गया। मैं अब जवाब पोस्ट करूंगा। –

उत्तर

1

मेरे पास कुछ विजेट्स के साथ गिटहब में एक प्रोजेक्ट है। यहाँ यह अपनी:

https://github.com/CyberEagle/AndroidWidgets

निम्नलिखित पैकेज में, वहाँ एडेप्टर CircularViewPager साथ प्रयोग किया जा करने के लिए कर रहे हैं: https://github.com/CyberEagle/AndroidWidgets/tree/master/src/main/java/br/com/cybereagle/androidwidgets/adapter

पहले, आप अपने लेआउट में ViewPager के बजाय CircularViewPager का प्रयोग करेंगे। सर्कुलर व्यूपेजर यहां है: https://github.com/CyberEagle/AndroidWidgets/blob/master/src/main/java/br/com/cybereagle/androidwidgets/view/CircularViewPager.java

यह व्यूपेगर एक पेजर एडाप्टर की बजाय एक रैपरक्रिकुलर पेजर एडाप्टर की अपेक्षा करता है। इस रैपर को व्यूपाजर को चालित करने के लिए उपयोग किया जाता है, यह सोचने के लिए कि व्यूपेजर में बहुत सी चीजें हैं, लेकिन यह वास्तव में परिपत्र प्रभाव बनाने के लिए आपके आइटम दोहराती है। तो, पेजर एडाप्टर, FragmentPagerAdapter या FragmentStatePagerAdapter को लागू करने के बजाय, आप या तो परिपत्रफ्रेगमेंट पेजर एडाप्टर, सर्कुलरफ्रैगमेंटस्टेट पेजर एडाप्टर या सर्कुलर पेजर एडाप्टर लागू करेंगे। फिर, आप अपने एडाप्टर को WrapperCircularPagerAdapter के साथ लपेटेंगे और अपने एडाप्टर की बजाय परिपत्र ViewPager में रैपर सेट करेंगे। साथ ही, जब डेटासेट को सूचित करने का समय बदल गया है, तो आप रैपर में अधिसूचना डेटासेट चेंज() को कॉल करेंगे।

सर्कुलर एडाप्टर में से किसी एक को लागू करते समय, आप देखेंगे कि तत्काल इटैम को लागू करने के बजाय, आपको तत्काल VirtualItem लागू करना होगा। टुकड़े के पेजर एडाप्टर के लिए, आप getItem के बजाय getVirtualItem लागू करेंगे। ऐसा इसलिए है क्योंकि मैंने आभासी वस्तुओं की अवधारणा बनाई है।

इसे स्पष्ट करने के लिए, 4 आइटम के साथ एक दृश्य पेजर की कल्पना करें, जिससे प्रत्येक आइटम संगीत का प्रतिनिधित्व करता है। जब आप बाईं ओर जाने के लिए जाते हैं, तो आप पहले के बाईं ओर चौथी वस्तु देखेंगे। असल में, यह एक पूरी नई वस्तु है, लेकिन यह वर्चुअल आइटम से जुड़ा हुआ है जो चौथे संगीत का प्रतिनिधित्व करता है।

एक और उदाहरण: कल्पना करें कि अब केवल एक संगीत है। आप बाईं ओर और दाईं ओर एक ही संगीत देखेंगे। एक समय में 3 आइटम हैं, लेकिन केवल एक वर्चुअल आइटम है।

तो, समझाया गया है कि, रैपर व्यूपाजर को छू रहा है, जिससे यह सोचता है कि बहुत सारी चीज़ें हैं। उपयोगकर्ता को ViewPager के सिरों में से किसी एक तक पहुंचने के लिए और अधिक कठिन बनाने के लिए (इसे किसी भी समय लंबा समय लगेगा), प्रत्येक बार डेटासेट में कोई परिवर्तन होता है, व्यूपेजर एक ही वर्चुअल आइटम पर जाता है, लेकिन इनमें से एक के लिए बीच के पास वास्तविक वस्तुओं।

एक और महत्वपूर्ण बात यह है कि सर्कुलर व्यूपेगर में विधि सेट है CurrentVirtualItem।यह विधि गणना करती है कि कौन सी वास्तविक वस्तु निकटतम वांछित वर्चुअल आइटम है और फिर यह सेट करने के लिए setCurrentItem का उपयोग करती है। आपके पास getCurrentVirtualItem का उपयोग करने का विकल्प भी है, जो वर्तमान वर्चुअल आइटम की अनुक्रमणिका लौटाएगा। ध्यान दें कि यदि आप getCurrentItem का उपयोग करते हैं, तो आपको एक बड़ी अनुक्रमणिका मिल जाएगी।

अच्छा, यह है। परियोजना के दस्तावेज़ीकरण की कमी के लिए मुझे खेद है। मैं इसे जल्द ही दस्तावेज की योजना बना रहा हूं। मैं रैपर की आवश्यकता को हटाने की भी योजना बना रहा हूं। कोड को कॉपी करने के लिए स्वतंत्र महसूस करें (अपाचे 2.0 लाइसेंस का सम्मान करना), कांटा या यहां तक ​​कि इसमें योगदान देना।

+0

मैंने आपके द्वारा उल्लेखित व्यू पेजर को लागू किया है। और जैसा कि आपने उपर्युक्त उल्लेख किया है, मैं आपके कक्षाओं परिपत्र ViewPager, WrapperCircularPagerAdapter और CircularFragmentPagerAdapter का उपयोग कर रहा हूं। लेकिन अभी भी अपवाद प्राप्त हो रहा है: अपवाद: java.lang.IllegalStateException: खंड के टैग को नहीं बदला जा सकता है। कोई सुझाव ? –

+0

यदि मैं 4 टुकड़े जोड़ता हूं तो मेरा कोड ठीक काम करता है। लेकिन मेरी आवश्यकताओं को केवल 2 टुकड़ों का उपयोग करना है जो –

+0

@MiaNKhaLiD से ऊपर अपवाद का कारण बनता है, यह अजीब है। यह मेरे लिए केवल एक टुकड़े के साथ भी काम किया। क्या आप मुझे दिखा सकते हैं कि आप इसका उपयोग कैसे कर रहे हैं? –

3

मैं जानता हूँ कि यह थोड़ी देर हो चुकी है, लेकिन यह है कि यह कैसे मेरे लिए काम किया:

मैं 3 टुकड़े के बीच एक परिपत्र कड़ी चोट की जरूरत है, तो मैं उन 3 और दो और मुझे पेज पाशन को लागू करने में मदद करने आभासी बनाया:

public static class FirstViewFragment extends Fragment { 
    // Empty Constructor 
    public FirstViewFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_landing_1, container, false); 
    } 
} 

public static class SecondViewFragment extends Fragment { 
    // Empty Constructor 
    public SecondViewFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_landing_2, container, false); 
    } 
} 

public static class ThirdViewFragment extends Fragment { 
    // Empty Constructor 
    public ThirdViewFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_landing_3, container, false); 
    } 
} 

और दो और आभासी टुकड़े जो मुझे अंतिम और दाएं से बाएं स्वाइप करने में सक्षम बनाता है। पहला आभासी फुलाते पिछले वास्तविक और पहली वास्तविक रूप में पिछले आभासी एक ही लेआउट के रूप में ही लेआउट:

public static class StartVirtualFragment extends Fragment { 
    public StartVirtualFragment() {} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_landing_3, container, false); 
    } 
} 

public static class EndVirtualFragment extends Fragment { 
    public EndVirtualFragment() {} 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.fragment_landing_1, container, false); 
    } 
} 

मेरे एडाप्टर:

private class ViewPagerAdapter extends FragmentPagerAdapter { 

    public ViewPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int i) { 
     switch (i) { 
      case 0: 
       return new StartVirtualFragment(); 
      case 1: 
       if (firstViewFragment == null) { 
        firstViewFragment = new FirstViewFragment(); 
       } 
       return firstViewFragment; 
      case 2: 
       if (secondViewFragment == null) { 
        secondViewFragment = new SecondViewFragment(); 
       } 
       return secondViewFragment; 
      case 3: 
       if (thirdViewFragment == null) { 
        thirdViewFragment = new ThirdViewFragment(); 
       } 
       return thirdViewFragment; 
      case 4: 
       return new EndVirtualFragment(); 
     } 
     return null; 
    } 

    @Override 
    public int getCount() { 
     return 5; 
    } 
} 

और मेरे पेज श्रोता मैं onPageScrollStateChanged इस्तेमाल किया स्थापित करने के लिए सही पृष्ठ और पाश को लागू:

:

viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
      if (state == ViewPager.SCROLL_STATE_DRAGGING) { 
       int pageCount = viewPager.getChildCount(); 
       int currentItem = viewPager.getCurrentItem(); 
       if (currentItem == 0) { 
        viewPager.setCurrentItem(pageCount - 2, false); 
       } else if (currentItem == pageCount - 1) { 
        viewPager.setCurrentItem(1, false); 
       } 
      } 
     } 
    }); 

और अंत में

आशा मैं

-2
**If you want to make 3 views visible at same time and make it circular** 

    public abstract class CircularPagerAdapter extends PagerAdapter{ 
     private int count; 
     int[] pagePositionArray; 
     public static final int EXTRA_ITEM_EACH_SIDE = 2; 
     private ViewPager.OnPageChangeListener pageChangeListener; 
     private ViewPager viewPager; 

     public CircularPagerAdapter(final ViewPager pager, int originalCount) { 
      super(); 
      this.viewPager = pager; 
      count = originalCount + 2*EXTRA_ITEM_EACH_SIDE; 
      pager.setOffscreenPageLimit(count-2); 
      pagePositionArray = new int[count]; 
      for (int i = 0; i < originalCount; i++) { 
       pagePositionArray[i + EXTRA_ITEM_EACH_SIDE] = i; 
      } 
      pagePositionArray[0] = originalCount - 2; 
      pagePositionArray[1] = originalCount -1; 
      pagePositionArray[count - 2] = 0; 
      pagePositionArray[count - 1] = 1; 

      pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 

       public void onPageSelected(final int position) { 
        if(pageChangeListener != null) 
        { 
         pageChangeListener.onPageSelected(pagePositionArray[position]); 
        } 

        pager.post(new Runnable() { 
         @Override 
         public void run() { 
          if (position == 1){ 
           pager.setCurrentItem(count-3,false); 
          } else if (position == count-2){ 
           pager.setCurrentItem(2,false); 
          } 
         } 
        }); 
       } 

       public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
        if(pageChangeListener != null) 
        { 
         pageChangeListener.onPageScrolled(pagePositionArray[position],positionOffset,positionOffsetPixels); 
        } 
       } 

       public void onPageScrollStateChanged(int state) { 
        if(pageChangeListener != null) 
        { 
         pageChangeListener.onPageScrollStateChanged(state); 
        } 
       } 
      }); 
     } 


     @Override 
     public int getCount() { 
      return count; 
     } 

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
      return false; 
     } 

     public abstract Object customInstantiateItem(ViewGroup container, int position); 

     public void setPageChangeListener(ViewPager.OnPageChangeListener pageChangeListener) 
     { 
      this.pageChangeListener = pageChangeListener; 
     } 

     @Override 
     public Object instantiateItem(ViewGroup container, int position) { 
      int pageId = pagePositionArray[position]; 
      return customInstantiateItem(container,pageId); 
     } 

     @Override 
     public void destroyItem(View container, int position, Object object) { 
      ((ViewPager) container).removeView((View) object); 
     } 

     public void setFirstItem() 
     { 
      viewPager.setCurrentItem(EXTRA_ITEM_EACH_SIDE - 1); 
     } 
    } 
संबंधित मुद्दे