Making the height of the ViewPager equal to the highest item in the PagerAdapter

1.2k Views Asked by At

I have a ViewPager and use it to swipe between views not Fragments . And when I give the View Pager wrap_content height , it doesn't show anything . So I had to give it a fixed height . But I had another problem , when the item's height is larger than the fixed one , the view doesn't be shown correctly (And I use TextView as the View) . So what should I do to make the height of the ViewPager is equal to the highest one .

I use PagerAdapter like the code below .

public class IndicatorViewPagerAdapter extends PagerAdapter {
    private Context context;
    public int[] images = {R.drawable.userprofile,R.drawable.userprofile,R.drawable.userprofile,R.drawable.userprofile,R.drawable.userprofile};
    public int[] texts = {R.string.first_text,R.string.second_text,R.string.third_text,R.string.fourth_text,R.string.fifth_text};
    LayoutInflater layoutInflater;
    Typeface typeface;
    String lang;
    public IndicatorViewPagerAdapter(Context context,String lang) {
        this.context = context;
        this.lang=lang;
    }

    @Override
    public int getCount() {
        return texts.length;
    }

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

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = layoutInflater.inflate(R.layout.feeds_item_layout,null);
        ImageView imageView = view.findViewById(R.id.image);
        TextView textView = view.findViewById(R.id.desc);
        imageView.setImageResource(images[position]);
        String text = context.getResources().getString(texts[position]);
        Log.e("text"," "+text);
        textView.setText(text);
        //ViewPager viewPager = (ViewPager) container;
        if(lang.equals("en")) {
            typeface = ResourcesCompat.getFont(context, R.font.knowledge_regular);
        }
        else {
            typeface = ResourcesCompat.getFont(context, R.font.thesans_plain);
        }
        textView.setTypeface(typeface);
        container.addView(view);


        return view;
    }

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


}

and Here I use the ViewPager in XML

<LinearLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/_150sdp"
                android:layout_marginTop="10dp"
                android:background="#85d7d5d6"
                android:orientation="horizontal"
                android:padding="10dp">

                <TextView
                    android:id="@+id/leftArrowTv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:textColor="@color/arrow_color"
                    android:textSize="@dimen/_20ssp" />

                <androidx.viewpager.widget.ViewPager
                    android:id="@+id/viewPager"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1" />

                <TextView
                    android:id="@+id/rightArrowTv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:textColor="@color/arrow_color"
                    android:textSize="@dimen/_20ssp" />

            </LinearLayout>
2

There are 2 best solutions below

2
Edward van Raak On

I don't quite understand why you posted your IndicatorViewPagerAdapter code.

Your adapter code is used to populate data, it has nothing to do with the size of the view, which is the ViewPager.

To me it probably makes more sense to try and customize the viewpager and apply manual resize logic. So I looked for this on stackoverflow, as found a popular stackoverflow post where you even commented on, but it seems you were also confused on how to actually implement it. To be clear, I haven't tested this at all but it seems you were confused by the difference between adapters and views.

public class WrapContentHeightViewPager extends ViewPager {

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

    public WrapContentHeightViewPager(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;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

Then change your XML to

            <TextView
                android:id="@+id/leftArrowTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:textColor="@color/arrow_color"
                android:textSize="@dimen/_20ssp" />

            <my.package.name.WrapContentHeightViewPager
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fillViewport="true" />

            <TextView
                android:id="@+id/rightArrowTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:textColor="@color/arrow_color"
                android:textSize="@dimen/_20ssp" />

        </LinearLayout>
3
Krishna Vyas On

I tried your code and it's working with a slight change. You just need to check your ViewPager item's design. ViewPager displays even with wrap_content height. Look at the below code:

@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
    View view = LayoutInflater.from(context).inflate(R.layout.feeds_item_layout,container, false);
    ...
    container.addView(view);
    return view;
}