您的位置:首页 > 其它

有关viewPager item数量相同数据不同时显示问题

2016-12-16 17:31 260 查看
当我们使用viewPager 设置数据后,如果只是更新了数据,但数据项数没变,那么当我们调用notifyDataSetChanged();里面的内容并不会刷新
跟踪下ViewPager的源码,主要是在下面这个函数
void dataSetChanged() {
// This method only gets called if our observer is attached, so mAdapter is non-null.

final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1 &&
mItems.size() < adapterCount;
int newCurrItem = mCurItem;

boolean isUpdating = false;
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
final int newPos = mAdapter.getItemPosition(ii.object);

if (newPos == PagerAdapter.POSITION_UNCHANGED) {
continue;
}

if (newPos == PagerAdapter.POSITION_NONE) {
mItems.remove(i);
i--;

if (!isUpdating) {
mAdapter.startUpdate(this);
isUpdating = true;
}

mAdapter.destroyItem(this, ii.position, ii.object);
needPopulate = true;

if (mCurItem == ii.position) {
// Keep the current item in the valid range
newCurrItem = Math.max(0, Math.min(mCurItem, adapterCount - 1));
needPopulate = true;
}
continue;
}

if (ii.position != newPos) {
if (ii.position == mCurItem) {
// Our current item changed position. Follow it.
newCurrItem = newPos;
}

ii.position = newPos;
needPopulate = true;
}
}

if (isUpdating) {
mAdapter.finishUpdate(this);
}

Collections.sort(mItems, COMPARATOR);

if (needPopulate) {
// Reset our known page widths; populate will recompute them.
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (!lp.isDecor) {
lp.widthFactor = 0.f;
}
}

setCurrentItemInternal(newCurrItem, false, true);
requestLayout();
}
}这里主要是needPopulate,如果是第一次刷新且有数据,mItems为0,adapterCount为当前要显示的item的数目(假设大于0),所有needPopulate为true进而调用setCurrentItemInternal
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
if (mAdapter == null || mAdapter.getCount() <= 0) {
setScrollingCacheEnabled(false);
return;
}
if (!always && mCurItem == item && mItems.size() != 0) {
setScrollingCacheEnabled(false);
return;
}

if (item < 0) {
item = 0;
} else if (item >= mAdapter.getCount()) {
item = mAdapter.getCount() - 1;
}
final int pageLimit = mOffscreenPageLimit;
if (item > (mCurItem + pageLimit) || item < (mCurItem - pageLimit)) {
// We are doing a jump by more than one page. To avoid
// glitches, we want to keep all current pages in the view
// until the scroll ends.
for (int i=0; i<mItems.size(); i++) {
mItems.get(i).scrolling = true;
}
}
final boolean dispatchSelected = mCurItem != item;

if (mFirstLayout) {
// We don't have any idea how big we are yet and shouldn't have any pages either.
// Just set things up and let the pending layout handle things.
mCurItem = item;
if (dispatchSelected) {
dispatchOnPageSelected(item);
}
requestLayout();
} else {
populate(item);
scrollToItem(item, smoothScroll, velocity, dispatchSelected);
}
}第一次mFirstLayout为true,调用requestLayout最终会调用到它的onMeasureonMeasure又调用populate,它又会执行
if (curItem == null && N > 0) {
curItem = addNewItem(mCurItem, curIndex);
}
ItemInfo addNewItem(int position, int index) {
ItemInfo ii = new ItemInfo();
ii.position = position;
ii.object = mAdapter.instantiateItem(this, position);
ii.widthFactor = mAdapter.getPageWidth(position);
if (index < 0 || index >= mItems.size()) {
mItems.add(ii);
} else {
mItems.add(index, ii);
}
return ii;
}

这里会调用adapter的initstantiateItem实例化一个item.

回到前面dataSetChanged,如果item里面已经有数据,并且数据项
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1 &&
mItems.size() < adapterCount;如果前面存在的item(mItem)的数量大于adapterCount,则needPopulate为false,不会刷新

目前解决的办法是每次拉到数据的时候重新new一个adapter并且设置到viewPager
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐