坑爹的ViewPager,坑爹ViewPager

來源:互聯網
上載者:User

坑爹的ViewPager,坑爹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);  }


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.