解決TabLayout+ViewPager+ListView,當ViewPager設置爲Wrap_content,不顯示viewpager的問題

網上很多的解釋都是對的,但是有所欠缺
直奔主題吧,本問題需要兩步來解決,注意哈,兩步
首先第一步,當然是要自定義ViewPager了
我這裏至貼出關鍵代碼了,網上有的是

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

然後run一下,發現 不好用,怎麼辦呢,因爲我們fragment中用的是ListView或者是RecycleListView,大概都一樣了,ViewPager爲啥設置Wrap-content不能顯示,那麼ListView就是爲啥不顯示的
所以我們的ListView也需要自定義一下

public class AdaptiveHeightListView extends ListView {

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

    public AdaptiveHeightListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AdaptiveHeightListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

再來說一下RecycleListView的解決方案
Fragment中不要使用單獨的RecyclerView作爲根佈局,而是使用一個Linearlayout(高度設置爲match_parent)作爲根佈局,裏面再嵌套一個RecyclerView(高度設置爲wrap_content)即可。

最後補上爲啥會出現這種狀況的原因吧
我們直接打開源碼就可以看到

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // For simple implementation, our 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));

    final int measuredWidth = getMeasuredWidth();
    final int maxGutterSize = measuredWidth / 10;
    mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize);
    ...
}

從註釋可以看到,viewPager把自己默認的size都是0,然後優先用父佈局傳過來的寬高,其效果就是寬高沒有指定的話就相當於match_parent,完全不考慮子view的屬性,因爲子view可以被動態的添加或刪除,寬高可能是不確定的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章