我有一个自定义 ViewGroup,它有一个子 ViewPager
。 ViewPager 由 PagerAdapter
提供,该 LinearLayout
向 ViewPager
提供 LayoutParams
的 WRAP_CONTENT
高度和宽度。
View 显示正确,但是当在 ViewPager 上调用 child.measure()
方法时,它不会返回 LinearLayout 的实际尺寸,但似乎会填满所有剩余空间。
任何想法为什么会发生这种情况以及如何修改它?
最佳答案
我对接受的答案不太满意(也不对评论中的 pre-inflate-all-views 解决方案),所以我整理了一个 ViewPager
,它的高度从第一个开始可用的 child 。它通过进行第二次测量来做到这一点,允许您窃取第一个 child 的高度。
更好的解决方案是在 android.support.v4.view
包中创建一个新类,该类实现更好的 onMeasure
版本(可以访问包- populate()
)
不过,就目前而言,下面的解决方案很适合我。
public class HeightWrappingViewPager extends ViewPager {
public HeightWrappingViewPager(Context context) {
super(context);
}
public HeightWrappingViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec)
== MeasureSpec.AT_MOST;
if(wrapHeight) {
/**
* The first super.onMeasure call made the pager take up all the
* available height. Since we really wanted to wrap it, we need
* to remeasure it. Luckily, after that call the first child is
* now available. So, we take the height from it.
*/
int width = getMeasuredWidth(), height = getMeasuredHeight();
// Use the previously measured width but simplify the calculations
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
/* If the pager actually has any children, take the first child's
* height and call that our own */
if(getChildCount() > 0) {
View firstChild = getChildAt(0);
/* The child was previously measured with exactly the full height.
* Allow it to wrap this time around. */
firstChild.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
height = firstChild.getMeasuredHeight();
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
关于android - 测量 ViewPager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9313554/