Android: I am unable to have ViewPager WRAP_CONTENT

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

I have setup a simple ViewPager that has an ImageView with a height of 200dp on each page.

Here is my pager:

pager = new ViewPager(this); pager.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); pager.setBackgroundColor(Color.WHITE); pager.setOnPageChangeListener(listener); layout.addView(pager);

Despite the height set as wrap_content, the pager always fills the screen even though the imageview is only 200dp. I tried to replace the height of the pager with "200" but that gives me different results with multiple resolutions. I am unable to add "dp" to that value. How do I add 200dp to the pager's layout?

回答1:

Overriding onMeasure of your ViewPager as follows will make it get the height of the biggest child it currently has.

@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); }


回答2:

Another more generic solution is to get wrap_content to just work.

I've extended ViewPager to override onMeasure(). The height is wraped around the first child view. This could lead to unexpected results if the child views are not exactly the same height. For that the class can be easily extended to let's say animate to the size of the current view/page. But I didn't need that.

You can use this ViewPager in yout XML layouts just like the original ViewPager:

Advantage: This approach allows using the ViewPager in any layout including RelativeLayout to overlay other ui elements.

One drawback remains: If you want to use margins, you have to create two nested layouts and give the inner one the desired margins.

Here's the code:

public class WrapContentHeightViewPager extends ViewPager {      /**      * Constructor      *      * @param context the context      */     public WrapContentHeightViewPager(Context context) {         super(context);     }      /**      * Constructor      *      * @param context the context      * @param attrs the attribute set      */     public WrapContentHeightViewPager(Context context, AttributeSet attrs) {         super(context, attrs);     }      @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         super.onMeasure(widthMeasureSpec, heightMeasureSpec);          // find the first child view         View view = getChildAt(0);         if (view != null) {             // measure the first child view with the specified measure spec             view.measure(widthMeasureSpec, heightMeasureSpec);         }          setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view));     }      /**      * Determines the height of this view      *      * @param measureSpec A measureSpec packed into an int      * @param view the base view with already measured height      *      * @return The height of the view, honoring constraints from measureSpec      */     private int measureHeight(int measureSpec, View view) {         int result = 0;         int specMode = MeasureSpec.getMode(measureSpec);         int specSize = MeasureSpec.getSize(measureSpec);          if (specMode == MeasureSpec.EXACTLY) {             result = specSize;         } else {             // set the height from the base view if available             if (view != null) {                 result = view.        
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!