您的位置:首页 > 其它

RossWeatherMap天气地图项目中踩的雷(一):Viewpager动态删除Fragment

2016-03-30 21:39 489 查看
开发环境:Myeclipse

JDK版本:1.7

Android版本:21

最近在做一个基于百度地图的天气APP,用的Fragment+ViewPager+DrawerLayout结构。具体就是使用两个带有BaiduMapView的Fragment显示全国天气,然后自定义的Fragment显示具体选中的城市的天气信息。现在已经可以显示具体城市的天气信息了,在研究如何把全国天气加在百度地图上。

来说说踩到的第一个雷吧。



点击tooglebutton后调用RemoveMapFragment删除MapFragment,再notifyDataSetChanged。

mDrawerToggleButton
.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (!isChecked) {
RemoveMapFragment();
mMyFragmentPagerAdapter.notifyDataSetChanged();

} else {
InitMapFragment();
mMyFragmentPagerAdapter.notifyDataSetChanged();
}
}

});


// 移除天气地图
private void RemoveMapFragment() {
Iterator<Fragment> iterator = mFragments.iterator();
while (iterator.hasNext()) {
Fragment f = iterator.next();
if (f instanceof MapFragment)
iterator.remove();
}
Log.d("RossWeatherMap", "已移除天气地图");
mMyFragmentPagerAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(0);}


Bug出现了,删除后仍然显示地图并且可以操纵,使用Debug工具可以看到此时Fragments中已经没有MapFragment



在百度查阅相关的问题发现这与ViewPager的缓存机制有关系,需要把FragmentPagerAdapter换成FragmentStatePagerAdapter才能使用,这里贴上原文地址:Android Viewpager动态删除Fragment解析

下面是修改后的FragmentStatePagerAdapter,之前用的是FragmentPagerAdapter

public class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {

private ArrayList<Fragment> mList;

public MyFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> list) {
super(fm);
mList = list;
notifyDataSetChanged();
}

@Override
public Fragment getItem(int arg0) {
return mList.get(arg0);
}

@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
@Override
public int getCount() {
return mList.size();
}

}


注:引用stackoverflow牛人的解决说明:

The ViewPager doesn’t remove your fragments with the code above because it loads several views (or fragments in your case) into memory. In addition to the visible view, it also loads the view to either side of the visible one. This provides the smooth scrolling from view to view that makes the ViewPager so cool.

使用以上代码不会让ViewPager移除你的Fragments因为它把多个view(或者Fragment)加载到了内存中。它不仅仅加载了当前可见的view,同时也加载了当前可见view两边的view。正是因为提供了view与view之间流畅的滑动才使得viewpager那么酷。

To achieve the effect you want, you need to do a couple of things.

为了达成你想要的效果,你需要做以下几件事。

Change the FragmentPagerAdapter to a FragmentStatePagerAdapter. The reason for this is that the FragmentPagerAdapter will keep all the views that it loads into memory forever. Where the FragmentStatePagerAdapter disposes of views that fall outside the current and traversable views.

把FragmentPagerAdapter改成FragmentStatePagerAdapter。这么做的原因是FragmentPagerAdapter会一直持有它加载进内存的views。而FragmentStatePagerAdapter则会处理那些超出当前及可遍历的views的view。

Override the adapter method getItemPosition (shown below). When we call mAdapter.notifyDataSetChanged(); the ViewPager interrogates the adapter to determine what has changed in terms of positioning. We use this method to say that everything has changed so reprocess all your view positioning。

重写adap的getItemPosition方法。当我们调用notifyDataSetChanged()方法时ViewPager会让adapter来决定在view的位置上有什么变化。通过return PagerAdapter.POSITION_NONE;我们告诉ViewPager所有view都变化了,请ViewPager重新生成所有的view。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  viewpager fragment