最近做項(xiàng)目遇到一個tab切換的選項(xiàng)的需求類似輪播圖损姜,用的是viewpager來做的据悔,遇到的問題是每個item的高度不一樣剿吻,所以在切換時需要每次去重新計算viewpager的高度箱玷,所以自定義了一個viewpager重寫onMeasure方法:
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(this.mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else {
int height = 0;
this.mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, 0));
int h = this.mCurrentView.getMeasuredHeight();
if(h > height) {
height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, 1073741824);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
然后在setPrimaryItem中重新設(shè)置viewpager高度
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
View view= (View) object;
((CustomPager) container).measureCurrentView(view);
}
但是在實(shí)際使用中發(fā)現(xiàn)setPrimaryItem會連續(xù)不斷的調(diào)用吮龄,最后研究后發(fā)現(xiàn)viewpager的onMeasure方法中會調(diào)用populate方法拷窜,而populate方法會調(diào)用setPrimaryItem方法开皿,所以才會導(dǎo)致死循環(huán),結(jié)果就是setPrimaryItem方法無限調(diào)用:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//省略部分源碼
populate();
}
void populate(int newCurrentItem) {
//省略部分源碼
mAdapter.setPrimaryItem(this, mCurItem, curItem != null ? curItem.object : null);
}
解決方法是重新自定義一個pageradapter篮昧,在里面記錄當(dāng)前的位置赋荆,位置變化時才會調(diào)用重新設(shè)置viewpager高度的方法:
public abstract class BasePagerAdapter extends PagerAdapter {
private int lastPosition = -1;
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (lastPosition != position && object instanceof DatePickerView && container instanceof CustomPager) {
lastPosition = position;
View view = (View) object;
((CustomPager) container).measureCurrentView(view);
}
}
}