安卓在ScrollView中巢狀ViewPager時,設定ViewPager的單個頁面高度隨內容變化
阿新 • • 發佈:2019-01-21
在開發過程中,有時候頁面佈局比較複雜,會使用到ScrollView和ViewPager,如果不進行處理,會出現不顯示ViewPager的子頁面,或者子頁面高度一樣,內容顯示不全,或者是留白太多。我的需求是需要在頁面下面加一個可以左右滑動的分欄,而且兩個分類的頁面高度不一致且不確定。一開始沒有考慮,直接就使用了ViewPager,但是子頁面什麼都沒有顯示,查了很多資料,說的都是這個問題。解決的方法也很簡單,我們只需要去計算一下每個子頁面的高度,然後儲存起來,在每次切換頁面的時候,去設定子頁面的高度就可以了,這裡自定義了一個ViewPager,也是參考網上大神的,出處忘記了,但是很好用啊。程式碼如下:
public class CustomViewPager extends ViewPager{ private HashMap<Integer, View> mMap = new LinkedHashMap<>(); private int current; private int height = 0; private boolean scrollable = true; public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMap.size() > current) { View child = getChildAt(current); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); height = child.getMeasuredHeight(); } // 得到ViewPager的MeasureSpec,使用固定值和MeasureSpec.EXACTLY, heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } // 重置頁面高度 public void resetHeight(int current) { this.current = current; if (mMap.size() > current) { LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams(); if (layoutParams == null) { layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height); } else { layoutParams.height = height; } setLayoutParams(layoutParams); } } public void setObjectForPosition(View view, int position) { mMap.put(position, view); } @Override public boolean onTouchEvent(MotionEvent ev) { if (!scrollable) { return true; } return super.onTouchEvent(ev); } public boolean isScrollable() { return scrollable; } public void setScrollable(boolean scrollable) { this.scrollable = scrollable; } }
程式碼相對比較簡單,應該都可以看懂的,自定義完之後,使用的方式和原生的ViewPager是一樣的,這裡不做多餘的介紹,只需要在使用的時候多加一個方法,去設定切換頁面時呼叫重置的方法:
mVp.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { mVp.resetHeight(position); } @Override public void onPageScrollStateChanged(int state) { } }); // 預設選中第一個 mVp.resetHeight(0);
這樣子就可以做到在切換頁面時,子頁面的高度和內容的高度一樣了。