问题描述
最近在自己开发的一款天气App里 主页面是viewpager+fragmnet 结构 城市天气是可以动态添加的,每次切换城市都是实时加载(这里去掉了viewpager的预加载),但在后来的测试中发现了一个极其严重的问题,就是每次添加2个以上Fragment后再进行增删城市城市的数据就完全对不上,取到的都是上一个城市的信息,一开始我以为是Bundle存取的问题,一直没法思路扩宽 贴下交互代码 避免踩坑
//MainActivity 通过循环 动态添加Fragment 并通过 newInstance 静态方法传递数据
for (int i = 0; i < citylist.size(); i++) {
String cityName = citylist.get(i).getDistrict();
String temperature = citylist.get(i).getTemperature();
WeatherFragment weatherFragment = new WeatherFragment().newInstance(cityName, i + "", note, picture, content);
weatherFragments.add(weatherFragment);
}
//获取从MainActivity中传递过来的数据 并通过bundle 存储
public static WeatherFragment newInstance(String cityName, String position, String note, String picture, String content) {
Log.e(TAG, "传参:" + cityName + "--" + position + "--" + note + "--" + picture + "--" + content);
WeatherFragment fragment = new WeatherFragment();
Bundle bundle = new Bundle();
bundle.putString("cityName", cityName);
bundle.putString("position", position);
bundle.putString("note", note);
bundle.putString("picture", picture);
bundle.putString("content", content);
fragment.setArguments(bundle);
return fragment;
}
原因分析:
最终经过多天的努力,发现这个问题是由于viewpager+fragment 在不退出当前Activity的情况下(因为我的项目里MainActivity加载后是不关闭状态)旧的Fragment没有被清除导致的 导致Bundle 获取的数据都是上一次的数据 ,真的是太坑了
解决方案:
这里就是重写FragmentPagerAdapter 重点是 clear 方法,在每次加载Fragment的时候调用这个clear方法,清除缓存 ,再让ViewPager重新设置适配器加载视图即可。
/**
* 重写FragmentPagerAdapter 解决主MainActivity 没有关闭的时候 Fragment 缓存问题
*/
public class ViewFragmentPagerAdapter extends FragmentPagerAdapter {
private FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction;
private Context mContext;
private List<WeatherFragment> mFragmentArrayList;
public ViewMaterialFragmentPagerAdapter(FragmentManager fm, Context ctx, List<WeatherFragment> fragments) {
super(fm);
mFragmentManager = fm;
mContext = ctx;
mFragmentArrayList = fragments;
}
@Override
public Fragment getItem(int i) {
return mFragmentArrayList.get(i);
}
@Override
public int getCount() {
return mFragmentArrayList.size();
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
/**
* 清除缓存fragment
*
* @param container ViewPager
*/
public void clear(ViewGroup container) {
if (this.mCurTransaction == null) {
this.mCurTransaction = this.mFragmentManager.beginTransaction();
}
for (int i = 0; i < mFragmentArrayList.size(); i++) {
long itemId = this.getItemId(i);
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = this.mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
//根据ID删除fragment,
mCurTransaction.remove(fragment);
}
}
mCurTransaction.commitNowAllowingStateLoss();
}
/**
* 父类的该方法是私有的,故重新定义
*
* @param viewId
* @param id
* @return
*/
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
}
例如:
pagerAdapter.clear(viewPager); viewPager.setAdapter(pagerAdapter);