ViewPager切换防止Fragment销毁以及取消Fragment的预加载
来源:互联网 发布:js this对象 编辑:程序博客网 时间:2024/05/22 13:26
存在的问题
1. 默认情况下,ViewPager会自动预加载
2. 切换过程中会销毁fragment视图
下面的图说明情况
如图,在Activity中使用ViewPager嵌套三个Fragment,当fragment1出现的时候,此时会预加载fragment2,滑动到fragment2会预加载fragment3,但是滑动到fragment3,此时会调用fragment1的destroyview方法,销毁视图。当重新滑动到fragment1才会重新调用fragment1的oncreateview方法。注意此时并不会销毁实例,不会调用ondestroy方法。
这样就存在两个问题
1、pagerview频繁切换,导致fragment1.fragment3在频繁的调用destroyview和oncreateview方法,重新创建视图。这样也浪费了大量的资源,用户体验不佳,虽然内存消耗比较低
2、因为切换到fragment1的时候,同时预加载了fragment2,如果此时fragment2也有大量的耗时网络请求要做,如果应用对启动反应速度比较敏感,所以此时做了多余的工作。或者说fragment2也会显示加载进度,显然不符合我们的预期,能否把这些耗时的工作延迟加载,也是个问题
防止频繁的销毁视图的解决方案
1、setOffscreenPageLimit(2)
2、或者重写PagerAdaper的destroyItem方法为空即可
笔者此处使用的是方案2
public class MyViewPagerAdapter extends FragmentPagerAdapter { ... @Override public void destroyItem(ViewGroup container, int position, Object object) { //如果注释这行,那么不管怎么切换,page都不会被销毁 //super.destroyItem(container, position, object); } }
取消预加载解决方案
介绍两个方法void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint(),它们分别用作设置/获得Fragment可见状态,我们可以重写Fragment在其中做判断。
第一步:重写Fragment
public abstract class BaseFragment extends Fragment{ /** Fragment当前状态是否可见 */ protected boolean isVisible; public void onCreate(android.os.Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(getUserVisibleHint()) { isVisible = true; onVisible(); } else { isVisible = false; onInvisible(); } } /** * 可见 */ protected void onVisible() { lazyLoad(); } /** * 不可见 */ protected void onInvisible() { } /** * 延迟加载 * 子类必须重写此方法 */ protected abstract void lazyLoad();}
第二步:继承BaseFragment
1、声明二个重要的变量
private boolean mHasLoadedOnce = false;private boolean isPrepared = false;
2、onCreateView中进行控件初始化,初始化完成后加载数据
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_layuot2, null); Dbug.d("","Fragment2==onCreateView"); initData(); isPrepared = true; lazyLoad(); return view; }
此处为什么要用isPrepared呢,因为lazyLoad();方法调用的时候控件可能没初始化完成,会报空指针错误。
3、lazyLoad中判断是否是首次加载和初始化完成
@Override protected void lazyLoad() { if (mHasLoadedOnce || !isPrepared) return; mHasLoadedOnce = true; }
4、onDestroyView中变量重置
@Override public void onDestroyView() { super.onDestroyView(); Dbug.d("","Fragment2==onDestroyView"); mHasLoadedOnce = false; isPrepared = false; }
- ViewPager防止Fragment销毁以及取消Fragment的预加载
- ViewPager防止Fragment销毁以及取消Fragment的预加载
- ViewPager防止Fragment销毁以及取消Fragment的预加载
- ViewPager防止Fragment销毁以及取消Fragment的预加载
- ViewPager防止Fragment销毁以及取消Fragment的预加载
- ViewPager切换防止Fragment销毁以及取消Fragment的预加载
- viewpager防止fragment销毁和以及取消fragment的预加载(平常开发时不怎么考虑这个问题)
- viewpager+fragment防止销毁和预加载问题
- 取消ViewPager中fragment的预加载
- ViewPager取消Fragment的预加载
- ViewPager+Fragment取消预加载
- Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用
- Fragment+Viewpager防止预加载
- viewpager+fragment 重写viewpager取消预加载
- ViewPager+Fragment取消预加载以及禁止滑动
- ViewPager+Fragment取消预加载、禁止滑动以及更新
- 解决ViewPager切换Fragment的销毁Fragment带来的问题
- 解决 viewpager fragment 切换 Fragment被销毁的问题
- Vim插件之vim-airline
- EL表达式和JSTL标签库
- 299美元企业级账号申请过程
- L1-035. 情人节
- 二叉搜索树实现简单字典
- ViewPager切换防止Fragment销毁以及取消Fragment的预加载
- 批量导入不受信任的证书及软件限制策略的应用
- HDOJ 5475 An easy problem(线段树)
- 香蕉派上安装FTP服务器
- Linux磁盘系统
- Activity中使用Fragment笔记
- Error:(13, 8) 错误: xxx不是抽象的, 并且未覆盖xxx中的抽象方法onBindViewHolder(BaseSimpleRecyclerAdapter.ViewHolder,int)
- 不一样的四月
- [LeetCode]506. Relative Ranks(相对应排名)