自定义ViewPager的高度

Android开发中,常会遇到侧滑翻页的效果,android.support.v4.view.ViewPager让这种实现变得简单易用,但是通常使用时,都是让ViewPager的宽和高去match_parent,或者布局时制定了ViewPager的高度,所以一切正常。偶然的一次布局改变,着实一头雾水了半天。

场景:页面某个区域显示ViewPager用来翻页,但是ViewPager中的试图并不是设计期加上去的,所以希望ViewPager可以wrap_content自适应child的高度,布局设计好后,感觉一切良好,因为最常用的各种layout设置wrap_content都能很好的工作,ViewPager也是容器,所以认为理所当然运行正常。

真正的运行app后发现,始终无法显示我动态添加进去的child,跟踪代码也未发现异常。好吧,那我们改一下布局,设定ViewPager的高度为100dp,再次运行,靠,啥都能看见了!

这会大家应该明白了吧,ViewPager设定wrap_content无效,他不会根据child视图去计算自己的高度,网上找到了ViewPager的onMeasure的代码,如下:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    // For simple implementation, or internal size is always 0.  
    // We depend on the container to specify the layout size of  
    // our view.  We can't really know what it is since we will be  
    // adding and removing different arbitrary views and do not  
    // want the layout to change as this happens.  
    setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),  
            getDefaultSize(0, heightMeasureSpec));  
  
    // Children are just made to fill our space.  
    mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() -  
            getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY);  
    mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() -  
            getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY);  
  
    // Make sure we have created all fragments that we need to have shown.  
    mInLayout = true;  
    populate();  
    mInLayout = false;  
  
    // Make sure all children have been properly measured.  
    final int size = getChildCount();  
    for (int i = 0; i < size; ++i) {  
        final View child = getChildAt(i);  
        if (child.getVisibility() != GONE) {  
            if (DEBUG) Log.v(TAG, "Measuring #" + i + " " + child  
      + ": " + mChildWidthMeasureSpec);  
            child.measure(mChildWidthMeasureSpec, mChildHeightMeasureSpec);  
        }  
    }  
}  

我们看到代码中并没有使用MeasureSpec.makeMeasureSpec去设定自己的实际高度,其实想想也是有道理的,ViewPager作为一个容器,和Linerlayout等是有不同的,ViewPager中可以增加不同的视图,但是他们不存在依赖关系,也没有线性布局的效果,所以假如你添加了n个视图,每个视图的高度都不一样,你让它按谁的高度去设定自己的高度呢,你要搞死它啊!代码中的官方注释也说明了这一点。

既然知道了这个原因,那如果我们需要让他适应我们自己的高度呢(假如我们添加的视图都是一样的),那么我们就继承ViewPager,然后重写onMeasure


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值