Infinite Scrolling Image ViewPager

后端 未结 7 784
Happy的楠姐
Happy的楠姐 2020-11-27 17:33

As documented by Google, the Gallery class was deprecated in API level 16. This widget is no longer supported. Other horizontally scrolling widgets include HorizontalScrollV

相关标签:
7条回答
  • 2020-11-27 17:39
     if ((pagerBottom.getCurrentItem() + 1) == (sliderimageDetails.size())) {
                                                pagerBottom.setCurrentItem(0);
                                            } else {
                                                pagerBottom.setCurrentItem((pagerBottom.getCurrentItem() + 1));
                                            }
    
    0 讨论(0)
  • 2020-11-27 17:41

    RecyclerViewPager has implement infinite scrolling and can scroll like a gallery.

    0 讨论(0)
  • 2020-11-27 17:44

    I found another solution, based on Shlomi Hasin and antonyt answers, without modifying collection.

    ViewPager yourPager;
    PagerAdapter yourAdapter;
    //....
    EndlessPagerAdapter endlessPagerAdapter = new EndlessPagerAdapter(yourAdapter, yourPager);
    yourPager.setAdapter(endlessPagerAdapter);
    yourPager.setCurrentItem(1);//for correct first page
    

    Full class:

    public class EndlessPagerAdapter extends PagerAdapter {
    
    private PagerAdapter adapter;
    
    public EndlessPagerAdapter(PagerAdapter adapter, ViewPager viewPager) {
        this.adapter = adapter;
        viewPager.addOnPageChangeListener(new SwapPageListener(viewPager));
    }
    
    @Override
    public int getCount() {
        return adapter.getCount() + 2;
    }
    
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (adapter.getCount() < 2) {
            adapter.instantiateItem(container, position);
        }
    
        int newPosition;
        if (position == 0) {
            newPosition = adapter.getCount() - 1;
        } else if (position >= getCount() - 1) {
            newPosition = 0;
        } else {
            newPosition = position - 1;
        }
        return adapter.instantiateItem(container, newPosition);
    }
    
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        adapter.destroyItem(container, position, object);
    }
    
    @Override
    public void finishUpdate(ViewGroup container) {
        adapter.finishUpdate(container);
    }
    
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return adapter.isViewFromObject(view, object);
    }
    
    @Override
    public void restoreState(Parcelable bundle, ClassLoader classLoader) {
        adapter.restoreState(bundle, classLoader);
    }
    
    @Override
    public Parcelable saveState() {
        return adapter.saveState();
    }
    
    @Override
    public void startUpdate(ViewGroup container) {
        adapter.startUpdate(container);
    }
    
    @Override
    public CharSequence getPageTitle(int position) {
        return adapter.getPageTitle(position);
    }
    
    @Override
    public float getPageWidth(int position) {
        return adapter.getPageWidth(position);
    }
    
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        adapter.setPrimaryItem(container, position, object);
    }
    
    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        adapter.unregisterDataSetObserver(observer);
    }
    
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        adapter.registerDataSetObserver(observer);
    }
    
    @Override
    public void notifyDataSetChanged() {
        adapter.notifyDataSetChanged();
    }
    
    @Override
    public int getItemPosition(Object object) {
        return adapter.getItemPosition(object);
    }
    
    private class SwapPageListener implements ViewPager.OnPageChangeListener {
    
        private ViewPager viewPager;
    
        SwapPageListener(ViewPager viewPager) {
            this.viewPager = viewPager;
        }
    
        @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_IDLE) {
                PagerAdapter pagerAdapter = viewPager.getAdapter();
                if (pagerAdapter != null) {
                    int itemCount = pagerAdapter.getCount();
                    if (itemCount < 2) {
                        return;
                    }
                    int index = viewPager.getCurrentItem();
                    if (index == 0 ) {
                        viewPager.setCurrentItem(itemCount - 2, false);
                    } else if (index == itemCount - 1) {
                        viewPager.setCurrentItem(1, false);
                    }
                }
            }
        }
    }}
    

    How it works:

    We have some collection

    then add two additional items to it

    show first element on last position and last element on first position

    add listener and swap pages on event, from 4 to 1 and from 0 to 3

    thats all.

    I would not advise you to apply animation there or heavy layouts, it can be lagging when elements swap.(maybe, I did not encounter any lags)

    Also don't set this adapter to pager more than once, or move SwapPageListener to external class and set it in initialization block.

    0 讨论(0)
  • 2020-11-27 17:46

    For infinite scrolling with days it's important you have the good fragment in the pager therefore I wrote my answer on this on page (Viewpager in Android to switch between days endlessly)

    It's working very well! Above answers did not work for me as I wanted it to work.

    0 讨论(0)
  • 2020-11-27 17:56

    I think my solution is simpler.

    Attention to my array of images structure:

    Item 0          => last image
    
    Item count()-1  => first image
    

    The trick is on onPageScrollStateChanged:

    When user scrolls to last item -> the pager jumps without animation to first image (position = 1)

    When user scrolls to first item -> the pager jumps without animation to last image (position = count - 2)

    public class InfiniteScrollingActivity extends ActionBarActivity {
    
        private ViewPager     pager;
        private MyAdapter     adapter;
        int[] promoImageIds = new int[]{R.drawable.cover6, R.drawable.cover1, R.drawable.cover2, R.drawable.cover3, R.drawable.cover4, R.drawable.cover5, R.drawable.cover6, R.drawable.cover1 };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_test);
    
            adapter = new MyAdapter(getSupportFragmentManager(), promoImageIds);
            pager = (ViewPager)findViewById(R.id.pager);
            pager.setAdapter(adapter);
            pager.setCurrentItem( 1 );
            pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageSelected(int index) {
                    Log.v( "onPageSelected", String.valueOf( index ) );
                }
    
                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // Log.v("onPageScrolled", "");
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
                    Log.v("onPageScrollStateChanged", String.valueOf(state));
    
                    if (state ==ViewPager.SCROLL_STATE_IDLE) {
                        int index = pager.getCurrentItem();
                        if ( index == 0 )
                            pager.setCurrentItem( adapter.getCount() - 2, false );
                        else if ( index == adapter.getCount() - 1 )
                            pager.setCurrentItem( 1 , false);
                    }
                }
            });
        }
    
    
        public static class MyAdapter extends FragmentPagerAdapter {
    
            int[] promoImageIds;
    
            public MyAdapter(FragmentManager fm, int[] promoImageIds){
                super(fm);
                this.promoImageIds = promoImageIds;
            }
    
            @Override
            public int getCount(){
                return promoImageIds.length;
            }
    
            @Override
            public Fragment getItem(int position) {
    
                return PromoFragment.newInstance( promoImageIds[position] );
            }
        }
    
        public static class PromoFragment extends Fragment
        {
            int imageID;
    
    
            static PromoFragment newInstance( int imageID)
            {
                PromoFragment f = new PromoFragment();
    
                // Supply num input as an argument.
                Bundle args = new Bundle();
                args.putInt( "imageID", imageID );
                f.setArguments(args);
    
                return f;
            }
    
            @Override
            public void onCreate(Bundle savedInstanceState)
            {
                super.onCreate(savedInstanceState);
                imageID = getArguments() != null ? getArguments().getInt( "imageID" ) : null;
            }
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState)
            {
                ImageView v = (ImageView) inflater.inflate(R.layout.fragment_image, container, false);
                v.setImageResource( imageID );
                return v;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 17:57

    I had the same problem, but I was able to find a way to solve it - the code can be found on github.

    If you copy the classes InfiniteViewPager and InfinitePagerAdapter into your project, you can achieve infinite (wrapped) scrolling with some small changes.

    In your Activity, wrap your PagerAdapter with an InfinitePagerAdapter:

    PagerAdapter adapter = new InfinitePagerAdapter(new ImagePagerAdapter(this, imageArra, stringArray));
    

    Change the ViewPager in the activity XML to be an InfiniteViewPager:

    <com.antonyt.infiniteviewpager.InfiniteViewPager 
           android:id="@+id/myimagepager" 
           android:layout_width="match_parent" 
           android:layout_height="match_parent" />
    

    You can rename the classes to whatever you want. This code only works if you have at least three pages (you have nine in your example code, so it will work fine for that).

    0 讨论(0)
提交回复
热议问题