RossWeatherMap天气地图项目中踩的雷(一):Viewpager动态删除Fragment
2016-03-30 21:39
489 查看
开发环境:Myeclipse
JDK版本:1.7
Android版本:21
最近在做一个基于百度地图的天气APP,用的Fragment+ViewPager+DrawerLayout结构。具体就是使用两个带有BaiduMapView的Fragment显示全国天气,然后自定义的Fragment显示具体选中的城市的天气信息。现在已经可以显示具体城市的天气信息了,在研究如何把全国天气加在百度地图上。
来说说踩到的第一个雷吧。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/b20e13b9dd3f907e53e21b334fa74431)
点击tooglebutton后调用RemoveMapFragment删除MapFragment,再notifyDataSetChanged。
Bug出现了,删除后仍然显示地图并且可以操纵,使用Debug工具可以看到此时Fragments中已经没有MapFragment
![](https://oscdn.geek-share.com/Uploads/Images/Content/202007/03/154491955bf6ab682bd94e5b3a6696c3)
在百度查阅相关的问题发现这与ViewPager的缓存机制有关系,需要把FragmentPagerAdapter换成FragmentStatePagerAdapter才能使用,这里贴上原文地址:Android Viewpager动态删除Fragment解析
下面是修改后的FragmentStatePagerAdapter,之前用的是FragmentPagerAdapter
注:引用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。
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。
相关文章推荐
- Android App开发中ViewPager组件的入门使用教程
- 使用ViewPager实现高仿launcher左右拖动效果
- Android Fragment 基本了解(图文介绍)
- Android应用中使用ViewPager实现类似QQ的界面切换效果
- Android中ViewPager组件的基本用法及实现图片切换的示例
- 灵活使用Android中ActionBar和ViewPager切换页面
- Android应用开发中Fragment与Activity间通信示例讲解
- Android中viewPager使用指南
- Android的Fragment的生命周期各状态和回调函数使用
- 浅谈Android App开发中Fragment的创建与生命周期
- Android Fragment的使用方法(翻译)
- Android 使用 ViewPager循环广告位的实现
- Android中ViewPager实现滑动指示条及与Fragment的配合
- 实例探究Android应用编写时Fragment的生命周期问题
- 详解Android App中ViewPager使用PagerAdapter的方法
- 使用Fragment来处理Andoird app的UI布局的实例分享
- Android viewpager中动态添加view并实现伪无限循环的方法
- Android应用中使用ViewPager和ViewPager指示器来制作Tab标签
- 详解Android App中创建ViewPager组件的方法
- Android App中ViewPager与Fragment结合的一些问题解决