今天遇到一个问题,就是在一个act中嵌套了viewpager,点击头部,会替换数据,然后刷新下面的viewpager所有的数据。我心里一想,不是也是FragmentPagerAdapter,然后一想应该有notifyDataSetChanged()方法,搞了下,确实有。但是不刷新数据,打断点也不重新执行fragment中的生命周期。心想应该是有复用机制了,无法强制刷新。度娘了下,确实是有的。
一、原因
1、解决方案一:
复写pageradapter的getItemPosition方法设置tag为POSITION_NONE意思是没有找到child要求重新加载。
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
这是网上找到的呼声最高的,然后继续执行了下,然后看到了fragment的生命周期确实执行了,但是数据还是那些数据。。。我。。
看下fragmentpageadapter中的源码,发现instantiateItem切换的方法中有这么直接的代码片说明了这个问题
Do we already have this fragment?
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
原来他会先去FragmentManager里面去查找有没有相关的fragment如果有就直接使用如果没有才会触发fragmentpageadapter的getItem方法获取一个fragment。所以你更新的fragmentList集合是没有作用的,还要清除FragmentManager里面缓存的fragment。解决办法:在继承的fragmentpageadapter类里面添加这么一个方法
二、解决方案
public void setFragments(ArrayList fragments) {
if(this.fragments != null){
FragmentTransaction ft = fm.beginTransaction();
for(Fragment f:this.fragments){
ft.remove(f);
}
ft.commit();
ft=null;
fm.executePendingTransactions();
}
this.fragments = fragments;
notifyDataSetChanged();
}
就能完美的解决fragmentpageadapter数据刷新。
三、BaseFragmentPagerAdapter完整代码片
package com.coofond.carservices.baseobj;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import java.util.List;
/**
* FragmentPagerAdapter
* viewpager强制刷新数据
* Created by IBM on 2016/10/12.
*/
public class BaseFragmentPagerAdapter extends FragmentPagerAdapter {
List<Fragment> fragmentList;
private FragmentManager fm;
//构造方法
public BaseFragmentPagerAdapter(FragmentManager fm, List<Fragment> list) {
super(fm);
this.fragmentList = list;
this.fm = fm;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void setFragments(List<Fragment> fragments) {
if (this.fragmentList != null) {
FragmentTransaction ft = fm.beginTransaction();
for (Fragment f : this.fragmentList) {
ft.remove(f);
}
ft.commit();
ft = null;
fm.executePendingTransactions();
}
this.fragmentList = fragments;
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
四、使用还是那个味道就是可以使用fragmentPagerAdapter.notifyDataSetChanged();了