在开发中我碰到了一个问题,当 Fragment 对应的数据集发生改变时,我希望能够通过调用 mAdapter.notifyDataSetChanged() 来触发 Fragment 页面使用新的数据调整或重新生成其内容,可是当我调用 notifyDataSetChanged() 后,发现什么都没发生。
在instantiateItem的时候,生成的fragment会存到FragmentManager中,下次再instantiateItem同一位置的item时候,会根据名字在FragmentManager寻找是否有缓存的fragment,如果有的话就会直接只用缓存的fragment,这就是导致Fragment数据集改变之后调用notifyDataSetChanged()方法也不会刷新的原因。
我们可以在设置了新的Fragment数据集之后,设置标记位,在instantiateItem中替换FragmentManager缓存的fragment 。

FragmentStatePagerAdapter 继承自 PagerAdapter, 当页面离开视线后,就会被消除,释放其资源。
代码:
public class FragmentDreamAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mList_Fragment = new ArrayList<>();
private HashMap<Integer, Boolean> mList_Need_Update = new HashMap<>();
private FragmentManager mFragmentManager;
private Context mContent;
public FragmentDreamAdapter(Context context, FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragmentManager = fm;
mList_Need_Update.clear();
mList_Fragment.clear();
this.mContent = context;
if (fragments != null) {
this.mList_Fragment.addAll(fragments);
}
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position); //得到缓存的fragment
Boolean update = mList_Need_Update.get(position);
if (update != null && update) {
String fragmentTag = fragment.getTag(); //得到tag,这点很重要
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.remove(fragment); //移除旧的fragment
fragment = getItem(position); //换成新的fragment
ft.add(container.getId(), fragment, fragmentTag); //添加新fragment时必须用前面获得的tag,这点很重要
ft.attach(fragment);
ft.commit();
mList_Need_Update.put(position, false); //清除更新标记(只有重新启动的时候需要去创建新的fragment对象),防止正常情况下频繁创建对象
}
return fragment;
}
public List<Fragment> getListFragment() {
return mList_Fragment;
}
public void setListFragment(List<Fragment> list_Fragment) {
// if(list_Fragment != null){
// FragmentTransaction ft = mFragmentManager.beginTransaction();
// for (int i = 0; i < mList_Fragment.size(); i++) {
// Fragment fragment = (Fragment) mList_Fragment.get(i);
// ft.remove(fragment);
// }
// ft.commit();
// ft = null;
// mFragmentManager.executePendingTransactions();
// }
mList_Need_Update.clear();
this.mList_Fragment.clear();
if (list_Fragment != null) {
this.mList_Fragment.addAll(list_Fragment);
}
notifyDataSetChanged();
}
public void setListNeedUpdate(List<Fragment> fragments) {
mList_Fragment.clear();
if (fragments != null) {
mList_Fragment.addAll(fragments);
}
mList_Need_Update.clear();
for (int i = 0; i < mList_Fragment.size(); i++) {
mList_Need_Update.put(i, true);
}
}
@Override
public Fragment getItem(int position) {
if (mList_Fragment.size() < position) {
return null;
}
return mList_Fragment.get(position);
}
@Override
public int getCount() {
return mList_Fragment.size();
}
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
try {
super.restoreState(state, loader);
} catch (Exception e) {
}
}
}
调用:
// 更新Fragment
mFPAdapter = new FragmentDreamAdapter(getContext(), getActivity().getSupportFragmentManager(), mFragments);
mFragments.clear();
for (int i = 0; i < tabMenus.size(); i++) {
mDataList.add(tabMenus.get(i).getNameEn());
mDataId.add(tabMenus.get(i).getId());
mFragments.add(new FavoritrsChildFragment(i, tabMenus.get(i)));
}
mFPAdapter.setListFragment(mFragments);
网友评论