公司做医疗产品的,显示操作用的是android。所以我就用上下两个部分大致是固定的,仅仅有中间会有6个页面的切换,当中会有两个用户的切换。即普通用户和管理员用户,图片能够大致展示一下
其他页面是同样的,就这两个页面不一样,以下的是管理员用户,一想到其他页面一样的,中间就用了一个ViewPager,然后为了缓存多个页面。用到了FragmentStatePagerAdapter,然后通过setOffscreenPageLimit(6)最多缓存了6个页面,这样一下,就不用操心每一个页面的fragment的声明周期对我项目的影响了。这个界面可能没有。可是其他界面的检測什么的,线程和Ui比較复杂。easy受fragment声明周期影响而crash。
可是这个里有个奇怪的要求,管理员用户的项目设置界面的功能居然不是全的,有两个在普通用户那边。这个设计我也非常纳闷,只是,还是得做啊,之后。就遇到了题目所说的问题,notifyDataSetChanged尽管会有页面的增多和降低,可是。项目界面就是不刷新。
然后找了度娘和谷哥,出来的答案大多指向同一篇文章http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDataSetChanged-does-not-work.html,稍微看了一遍,照着上面方法试了。报错。依然不得其要领,然后自己去看了下源代码,攻克了。分享并记住这个问题,免得以后再犯错
先进入notifyDataSetChanged
发现这句,mObservable,看名字,观察者,应该就是用来实时监測viewPager绑定数据源的变化的。再进入notifychanged方法
发现一个遍历。这个遍历会去调用mObservers中的每个元素的变化。我们再进入onChanged,
到了,这里,发现onChanged仅仅是一个抽象类中的方法。,既然会调用,肯定会被重写咯,找了一圈。在viewPager中的内部内继承了。
躲的还是蛮深的,只是这还没有找到我们须要关注的地方,那就继续找,dataSetChanged
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(); } }这里就是我们须要关注的地方了,一看这么多。确实有点头疼。只是,我们仅仅关注重点,看第13行,有句
final int newPos = mAdapter.getItemPosition(ii.object);
这里就调用的了我们的adapter中的getItemPosition,我们再看看getItemPosition会返回什么,会接收什么,复写fragmentStatePagerAdapter中的getItemPosition方法,发现仅仅会返回父类中的方法
接着看父类中的方法
再看看POSITION_UNCHANGED是干嘛用的。
马丹,这下总算是明确了,这里一直return POSITION_UNCHANGED;
return一个“未改变”的标志给dataSetChanged()中,它当然打死都不更新咯。请看dataSetChanged()中的第15-17行
魂淡,居然知道原因了。那就好做了。直接将要刷新的页面 return POSITION_NONE
@Override public int getItemPosition(Object object) { if (object.getClass().getName().equals(ProjectFragment.class.getName()) || object.getClass().getName().equals(ProjectFragment2.class.getName())) { return POSITION_NONE; } return super.getItemPosition(object);}
本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5330584.html,如需转载请自行联系原作者