7

Is it possible to use ViewPager without fragments? All examples i could find load several fragments to the ViewPager.

I want to use it similarly to a ListView. I would like to create a custom adapter that will inflate a layout according to the position the pager is in.

if it's possible can anyone point me to an example for that ?

Mortalus
  • 10,574
  • 11
  • 67
  • 117

3 Answers3

11

I had the similar problem and it took me some time to figure it out. Posting my adapter here for future reference.

/**
 * A page adapter which works with a large data set by reusing views.
 */
public abstract class ListPageAdapter<T> extends PagerAdapter {

  // Views that can be reused.
  private final List<View> mDiscardedViews = new ArrayList<View>();
  // Views that are already in use.
  private final SparseArray<View> mBindedViews = new SparseArray<View>();

  private final ArrayList<T> mItems;
  private final LayoutInflater mInflator;
  private final int mResourceId;

  public ListPageAdapter(Context context, int viewRes) {
    mItems = new ArrayList<T>();
    mInflator = LayoutInflater.from(context);
    mResourceId = viewRes;
  }

  @Override
  public int getCount() {
    return mItems.size();
  }

  @Override
  public boolean isViewFromObject(View v, Object obj) {
    return v == mBindedViews.get(mItems.indexOf(obj));
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    View view = mBindedViews.get(position);
    if (view != null) {
      mDiscardedViews.add(view);
      mBindedViews.remove(position);
      container.removeView(view);
    }
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    View child = mDiscardedViews.isEmpty() ?
        mInflator.inflate(mResourceId, container, false) :
          mDiscardedViews.remove(0);

    T data = mItems.get(position);
    initView(child, data, position);

    mBindedViews.append(position, child);
    container.addView(child, 0);
    return data;
  }

  public void add(T item) {
    mItems.add(item);
  }

  public T remove(int position) {
    return mItems.remove(position);
  }

  public void clear() {
    mItems.clear();
  }

  /**
   * Initiate the view here
   */
  public abstract void initView(View v, T item, int position);
}

The viewPager is not updated automatically when the data is changed int the adapter. For that I used

pager.setAdapter(null);
pager.setAdapter(myAdapter);
pager.setCurrentItem(0);
Painless
  • 176
  • 4
7

Yes its totally possible. Since ViewPager.setAdapter() takes any instance PageAdapter, you just need to create your own subclass of PagerAdapter (its kinda like subclassing BaseAdapter or ArrayAdapter that you use in a ListView). just remember, for PAgerAdapter the docs say:

When you implement a PagerAdapter, you must override the following methods at minimum:

Hope this helps

petey
  • 16,914
  • 6
  • 65
  • 97
0

This is a Kotlin solution. Set an object of this class as adapter of the viewPager-

class PageAdapter : PagerAdapter() {
    private val pageLayouts = listOf(R.layout.home_page_1, R.layout.home_page_2)

    override fun instantiateItem(container: ViewGroup, position: Int): Any =
        LayoutInflater.from(container.context).inflate(pageLayouts[position], container, false).apply {
            container.addView(this)
        }

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) =
        container.removeView(`object` as View)

    override fun getCount(): Int = 2

    override fun isViewFromObject(view: View, `object`: Any): Boolean = (view == `object`)
}
Gulshan
  • 3,611
  • 5
  • 35
  • 46