PagerAdapter的setPrimaryItem无限调用
2017-11-17 本文已影响133人
hongSirX
最近做项目遇到一个tab切换的选项的需求类似轮播图,用的是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中重新设置viewpager高度
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
View view= (View) object;
((CustomPager) container).measureCurrentView(view);
}
但是在实际使用中发现setPrimaryItem会连续不断的调用,最后研究后发现viewpager的onMeasure方法中会调用populate方法,而populate方法会调用setPrimaryItem方法,所以才会导致死循环,结果就是setPrimaryItem方法无限调用:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//省略部分源码
populate();
}
void populate(int newCurrentItem) {
//省略部分源码
mAdapter.setPrimaryItem(this, mCurItem, curItem != null ? curItem.object : null);
}
解决方法是重新自定义一个pageradapter,在里面记录当前的位置,位置变化时才会调用重新设置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);
}
}
}