otak info official Logo   
OTAK.INFO
Personal Blog

Hariyanto Lim

정길상 / 鄭吉祥
Home   Last Posts  
 
Please login to see more topics and discussion categories.
 
goto main category list >> Software programming >> Android

Title : Simplest Infinite ViewPager
Total Reply : 0
Total View : 1327


Harry
Harry
Total thread: 131
Total reply: 50

Post #175
Simplest Infinite ViewPager
In almost all of my Android projects, I have the requirement to implement infinite loop ViewPager, previously I have use other people code, but today finally I made my own simplest implementation without making custom ViewPager, only extends PagerAdapter.

HInfiniteViewPagerAdapter.java
package info.otak.adapter;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
import info.otak.util.LogHelper;

public class HInfiniteViewPagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {

	private final String TAG = HInfiniteViewPagerAdapter.class.getSimpleName();

    private ViewPager mViewPager;

    private List<HAdapterData> mData;

    private int realItemCount;
    private int virtualItemCount;

    private boolean isSupportInfiniteLoop = false;

    public HInfiniteViewPagerAdapter(ViewPager vp, List<HAdapterData> dataList) {

        mViewPager = vp;

        mData = dataList;

        realItemCount = mData == null ? 0 : mData.size();

        if(realItemCount >= 2) {
            virtualItemCount = realItemCount + 2;
            isSupportInfiniteLoop = true;

            // use MAXIMUM POSSIBLE cache size to avoid calling multiple instantiateItem() because destroyItem() !!!
            mViewPager.setOffscreenPageLimit(realItemCount); // MAX cache size

        } else {
            // item less than requirement, can not support infinite swipe/loop
            virtualItemCount = realItemCount;

            isSupportInfiniteLoop = false;
        }

        mViewPager.setAdapter(this);
        mViewPager.addOnPageChangeListener(this);
    }

    @Override
    public int getCount() {
        //LogHelper.d(TAG, "getCount() : " + virtualItemCount);
        return virtualItemCount;
    }

    public int getRealItemCount() {
        return realItemCount;
    }

    public boolean isSupportInfiniteLoop() {
        return isSupportInfiniteLoop;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        //LogHelper.d(TAG, "isViewFromObject(View, Object)");
        return view == object;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        int realItemPosition = getRealItemPosition(position);

        return getRealItemPageTitle(realItemPosition);
    }

    public CharSequence getRealItemPageTitle(int realItemPosition) {
        String title = mData.get(realItemPosition).title;

        LogHelper.d(TAG, "getRealItemPageTitle(" + realItemPosition + ") : " + title);

        return title;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //super.destroyItem(container, position, object);

        //int realItemPosition = getRealItemPosition(position);

        container.removeView((View) object);

        LogHelper.d(TAG, "destroyItem(ViewGroup, position: " + position + ", Object)");
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        int realItemPosition = getRealItemPosition(position);

        LogHelper.d(TAG, "instantiateItem(ViewGroup, position: " + position + "), real item position: " + realItemPosition);

        TextView tv = new TextView(container.getContext());

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        tv.setLayoutParams(params);
        tv.setGravity(Gravity.CENTER);

        String description = mData.get(realItemPosition).description;
        tv.setText(description);

        LogHelper.d(TAG, "instantiateItem(ViewGroup, position: " + position + ") : " + description);

        container.addView(tv);

        return tv;
    }

    /**
     *
     * @param virtualItemPosition
     * @return value 0 to (realItemCount - 1)
     */
    public int getRealItemPosition(int virtualItemPosition) {

        if(isSupportInfiniteLoop) {
            int realItemPosition = virtualItemPosition;

            if(virtualItemPosition < 1) {
                // over FIRST real item position, so return LAST real item position
                realItemPosition = realItemCount - 1;
            } else if(virtualItemPosition > realItemCount) {
                // over LAST real item position, so return FIRST real item position
                realItemPosition = 0;
            } else {
                // at this point, it means :: "1 <= virtualItemPosition <= realItemCount"
                realItemPosition = (virtualItemPosition - 1);// % realItemCount;
            }

            LogHelper.d(TAG, "getRealItemPosition(" + virtualItemPosition + ") : " + realItemPosition + " [support infinite loop: true]");

            return realItemPosition;
        }

        LogHelper.d(TAG, "getRealItemPosition(" + virtualItemPosition + "), does not support infinite loop, so there is no logic, just return the value");
        return virtualItemPosition;
    }

    /**
     * set real item position from external classsuch as PagerSlidingTabStrip or manual set
     * @param realItemPosition
     */
    public void setRealItemPosition(int realItemPosition) {
        LogHelper.d(TAG, "setRealItemPosition(" + realItemPosition + ")");

        if(isSupportInfiniteLoop) {
            if(realItemPosition >= realItemCount) {
                // set the last VIRTUAL item position
                mViewPager.setCurrentItem(virtualItemCount - 1);
            } else if(0 <= realItemPosition && realItemPosition < realItemCount){
                mViewPager.setCurrentItem(realItemPosition + 1);
            } else {
                throw new IllegalArgumentException("setRealItemPosition(" + realItemPosition + "), value can NOT be negative !!");
            }
        }
    }

    // ---------------- start of "implements ViewPager.OnPageChangeListener" interfaces ---------------

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {
        if(isSupportInfiniteLoop) {
            int realItemPosition = getRealItemPosition(position);

            // change position ONLY IF past FIRST REAL ITEM POSITION or LAST REAL ITEM POSITION !!!
            if (position > realItemCount) {
                LogHelper.d(TAG, "onPageSelected(virtualItemPosition: " + position + "), over last item, so display the first item");
                mViewPager.setCurrentItem(1, false); // jump direct without animation
            } else if (position < 1) {
                LogHelper.d(TAG, "onPageSelected(virtualItemPosition: " + position + "), over the first item, so display last item");
                mViewPager.setCurrentItem(realItemCount, false); // jump direct without animation
            } else {
                LogHelper.d(TAG, "onPageSelected(virtualItemPosition: " + position + "), real item position: " + realItemPosition);
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}

    // ---------------- end of "implements" interfaces ---------------

    public static class HAdapterData {
        public String title;
        public String description;

        public HAdapterData(String title, String description) {
            this.title = title;
            this.description = description;
        }
    }
}


How to use it:
vp = (ViewPager) findViewById(R.id.vp_main);

List<HAdapterData> data = new ArrayList<HInfiniteViewPagerAdapter.HAdapterData>();
data.add(new HAdapterData("one 1", "this is one"));
data.add(new HAdapterData("two 22", "this is two"));
data.add(new HAdapterData("three 333", "this is three lah"));
data.add(new HAdapterData("four 4444", "this is four as in 4"));
data.add(new HAdapterData("five 55555", "this is five O Hawaii"));
data.add(new HAdapterData("six 666666", "this is six"));
data.add(new HAdapterData("seven 7777777", "this is seven lucky triple 777"));
data.add(new HAdapterData("eight 8", "this is eight"));
data.add(new HAdapterData("nine 9", "this is nine"));
data.add(new HAdapterData("ten ships", "this is ten o ten ten o"));

// BIND ViewPager and Adapter !!
mAdapter = new HInfiniteViewPagerAdapter(vp, data);
Falling in love with the world

Write : 2016-05-27 11:50:07

If you want to create a new reply then please login first.



www.OTAK.INFO
Since 19 January 2007
Page hit : 688,016

Code update 24th June 2013
Brain is a very capable to solve big problems
but requires constant reminders about how to.
peace bird