1

I would like to know if is it possible to have a PagerAdapter with wrap_content without using getChildCount() and getChildAt(i)? I have checked the answer below, but since on my adapter doesn't have children it doesn't work.

https://stackoverflow.com/a/20784791/10020799

Does someone know how to make an wrap_content adapter in this case? My PagerAdapter code is:

public class SectionsPagerAdapter extends PagerAdapter {
    private Integer pagerTotal = 10;

    public SectionsPagerAdapter(Context c) {
        super();
        inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void setPagerTotal(Integer item) {
        pagerTotal = item;
    }

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

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

        LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.home_top_page, null);
        container.addView(layout);

        topMain = (ImageView) layout.findViewById(R.id.top_main);

        if(imageBitmapArray != null && imageBitmapArray.length > 0){
            topMain.setImageBitmap(imageBitmapArray[position]);
        }else{
            if(intImageArray != null) {

                    topMain.setImageResource(R.drawable.top_main_01);
            }
        }

        return layout;
    }

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

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }
}
L Kemp
  • 2,260
  • 2
  • 8
  • 11

2 Answers2

0

You can resize the ViewPager to it's current page size on page swipe from this answer.

You can use the following code:

 public class WrapContentViewPager extends ViewPager {

        private int mCurrentPagePosition = 0;

        public WrapContentViewPager(Context context) {
            super(context);
        }

        public WrapContentViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        try {
             boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;
             if (wrapHeight) {
                 View child = getChildAt(mCurrentPagePosition);
                 if (child != null) {
                 child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                 int h = child.getMeasuredHeight();

                 heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
                }
            }
    } catch (Exception e) {
        e.printStackTrace();
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

        public void reMeasureCurrentPage(int position) {
            mCurrentPagePosition = position;
            requestLayout();
        }
    }

Use it in xml:

    <your.package.name.WrapContentViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    </your.package.name.WrapContentViewPager>

After that call reMeasureCurrentpage function on page swipe.

    final WrapContentViewPager wrapContentViewPager = (WrapContentViewPager) findViewById(R.id.view_pager);

    wrapContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                }

                @Override
                public void onPageSelected(int position) {
                    wrapContentViewPager.reMeasureCurrentPage(wrapContentViewPager.getCurrentItem());
                }

                @Override
                public void onPageScrollStateChanged(int state) {

                }
            });

Note that a list can have hundreds of items then this is not good to use this wrap_content ViewPager.

Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
0

Even with a not expandable adapter is possible to use getChildCount() and getChildAt(i) functions. Based on Khemraj's answer and this post's answer, I was able to solve the problem with the following code:

class:

public class WrapContentViewPager extends ViewPager {

    public WrapContentViewPager(Context context) {
        super(context);
    }

    public WrapContentViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if(h > height) height = h;
        }

        if (height != 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

xml:

<your.package.name.WrapContentViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
</your.package.name.WrapContentViewPager>

on page swipe:

final WrapContentViewPager wrapContentViewPager = (WrapContentViewPager) findViewById(R.id.view_pager);

wrapContentViewPager.addOnPageChangeListener(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) {

            }
        });
L Kemp
  • 2,260
  • 2
  • 8
  • 11