原文链接:http://blog.csdn.net/linglongxin24/article/details/53205878

Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

在Android中我们经常会用到ViewPager+Fragment组合。然而,有一个很让人头疼的问题就是,我们去加载数据的时候由于ViewPager的内部机制所限制,所以它会默认至少预加载一个。这让人很郁闷,所以,我就想到要封装一个Fragment来解决这个问题。

这里还解决一个问题就是在Android酷炫欢迎页播放视频,仿蚂蜂窝自由行和慕课网,这里感谢有一位网友提出了bug,就是在播放视频的时候如果滑动到第二页和第三页,第一页的视频还在播放,这是个让人很头疼的问题,在这里也完美解决。

1.问题初探

文章开始已经说过ViewPager的预加载机制。那么,我们可不可以设置ViewPager的预加载为0,不就解决问题了吗?

vp.setOffscreenPageLimit(0);

经过测试发现,根本不是这么回事,为什么呢?我们来看看Viewpager的setOffscreenPageLimit()方法的源码

 private static final int DEFAULT_OFFSCREEN_PAGES = 1;/*** Set the number of pages that should be retained to either side of the* current page in the view hierarchy in an idle state. Pages beyond this* limit will be recreated from the adapter when needed.** <p>This is offered as an optimization. If you know in advance the number* of pages you will need to support or have lazy-loading mechanisms in place* on your pages, tweaking this setting can have benefits in perceived smoothness* of paging animations and interaction. If you have a small number of pages (3-4)* that you can keep active all at once, less time will be spent in layout for* newly created view subtrees as the user pages back and forth.</p>** <p>You should keep this limit low, especially if your pages have complex layouts.* This setting defaults to 1.</p>** @param limit How many pages will be kept offscreen in an idle state.*/public void setOffscreenPageLimit(int limit) {if (limit < DEFAULT_OFFSCREEN_PAGES) {Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "+ DEFAULT_OFFSCREEN_PAGES);limit = DEFAULT_OFFSCREEN_PAGES;}if (limit != mOffscreenPageLimit) {mOffscreenPageLimit = limit;populate();}}

我们发现,即使你设置为0,那么还是会在里面判断后设为默认值1。所以这个方法是行不通的。

2.问题再探

我们发现Fragment中有一个setUserVisibleHint(boolean isVisibleToUser)方法,这个方法就是告诉用户,UI对用户是否可见,那么我们在这里去加载数据会怎么样呢?

这又是为什么呢?
因为ViewPager会加载好多Fragment,为了节省内容等会在Fragment不可见的某个时候调用onDestroyView()将用户界面销毁掉但是Fragment的实例还在,所以可能第一次加载没有问题,
但是再次回到第一个Fragment再去加载的时候就会出现UI对用户可见但是视图还没有初始化。

3.最终解决方案

package cn.bluemobi.dylan.viewpagerfragmentlazyload;import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;/*** Fragment预加载问题的解决方案:* 1.可以懒加载的Fragment* 2.切换到其他页面时停止加载数据(可选)* Created by yuandl on 2016-11-17.* blog :http://blog.csdn.net/linglongxin24/article/details/53205878*/public abstract class LazyLoadFragment extends Fragment {/*** 视图是否已经初初始化*/protected boolean isInit = false;protected boolean isLoad = false;protected final String TAG = "LazyLoadFragment";private View view;@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {view = inflater.inflate(setContentView(), container, false);isInit = true;/**初始化的时候去加载数据**/isCanLoadData();return view;}/*** 视图是否已经对用户可见,系统的方法*/@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);isCanLoadData();}/*** 是否可以加载数据* 可以加载数据的条件:* 1.视图已经初始化* 2.视图对用户可见*/private void isCanLoadData() {if (!isInit) {return;}if (getUserVisibleHint()) {lazyLoad();isLoad = true;} else {if (isLoad) {stopLoad();}}}/*** 视图销毁的时候讲Fragment是否初始化的状态变为false*/@Overridepublic void onDestroyView() {super.onDestroyView();isInit = false;isLoad = false;}protected void showToast(String message) {if (!TextUtils.isEmpty(message)) {Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();}}/*** 设置Fragment要显示的布局** @return 布局的layoutId*/protected abstract int setContentView();/*** 获取设置的布局** @return*/protected View getContentView() {return view;}/*** 找出对应的控件** @param id* @param <T>* @return*/protected <T extends View> T findViewById(int id) {return (T) getContentView().findViewById(id);}/*** 当视图初始化并且对用户可见的时候去真正的加载数据*/protected abstract void lazyLoad();/*** 当视图已经对用户不可见并且加载过数据,如果需要在切换到其他页面时停止加载数据,可以覆写此方法*/protected void stopLoad() {}}
}

4.用法

LazyLoadFragment是一个抽象类,可以作为BaseFragment,继承它。

(1).用setContentView()方法去加载要显示的布局

(2).lazyLoad()方法去加载数据

(3).stopLoad()方法可选,当视图已经对用户不可见并且加载过数据,如果需要在切换到其他页面时停止加载数据,可以覆写此方法

package cn.bluemobi.dylan.viewpagerfragmentlazyload;import android.util.Log;/**
* Created by yuandl on 2016-11-17.
*/public class Fragment1 extends LazyLoadFragment {@Overridepublic int setContentView() {return R.layout.fm_layout1;}@Overrideprotected void lazyLoad() {String message = "Fragment1" + (isInit ? "已经初始并已经显示给用户可以加载数据" : "没有初始化不能加载数据")+">>>>>>>>>>>>>>>>>>>";showToast(message);Log.d(TAG, message);}@Overrideprotected void stopLoad() {Log.d(TAG, "Fragment1" + "已经对用户不可见,可以停止加载数据");}
}

5.看效果界面

6.GitHub

ViewPager+Fragment懒加载相关推荐

  1. viewpager+fragment 懒加载

    大家都知道viewpager默认会加载下一页数据,viewpager提供了一个方法setOffscreenPageLimit(),设置预加载页数 懒加载字面意思当需要的时候才去加载,不需要时不加载 之 ...

  2. Androidx ViewPager+Fragment 懒加载

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/113545036 本文出自[赵彦军的博客] 目录 前言 懒加载(预加载) 传统模式 ...

  3. Fragment 懒加载

    为何懒加载 在很多 App 都会有ViewPage + Fragment 的基本组合,但是众所周知 viewPager 的 预加载机制,即使设置函数 setOffscreenPageLimit(0) ...

  4. 【Android】再来一篇Fragment懒加载(只加载一次哦)

    本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 使用前需知 2017-7-14更新: 目前有人使用后出现了诸如首次打开显示空白界面,但点击有反应:或来回切换又变空白界面的问题.这些 ...

  5. Fragment懒加载(三)

    老实说,我没想到我会写关于Fragment懒加载的第三章内容,我之前是打算写两章就完结了,以我的知识储备,我就只认为懒加载只是为了配合viewpager防止预加载而已,然后我错了,我没想到Fragme ...

  6. 带你深入了解Fragment懒加载

    Fragment懒加载是一种优化技术,用于在Android应用中延迟加载和初始化Fragment的内容,以提高应用性能和用户体验.它的核心思想是只有在Fragment可见时才加载数据和执行相关操作,而 ...

  7. Android——Fragment懒加载

    Fragment懒加载 简述 LazyFragment 简述 大部分APP框架由一个单例MainActivity和多个Fragment组成:在实际开发中常使用BottomNavigationView+ ...

  8. Fragment结合ViewPager之懒加载

    什么是懒加载?为什么要用懒加载?### 1.什么是懒加载 懒加载就是当ViewPager和Fragment结合在一起使用时,Fragment呈现在用户面前时才加载数据,当其从未被呈现在用户面前时,不会 ...

  9. 【Android】Fragment懒加载和ViewPager的坑

    本篇文章已授权微信公众号 安卓巴士Android开发者门户 独家发布 效果 老规矩,先来看看效果 ANDROID和福利两个Fragment是设置的Fragment可见时加载数据,也就是懒加载.圆形的旋 ...

最新文章

  1. SAP CV02N 审批一个文档
  2. 关于IOCP乱序的探讨
  3. 决策树原理实例(python代码实现)_决策树原理实例(python代码实现)
  4. Linux 查看文件位置/查看文件路径的命令
  5. 领域驱动设计(DDD)前夜:面向对象思想
  6. Java并发编程(07):Fork/Join框架机制详解
  7. web应用程序和Web网站区别
  8. PHP store session with couchbase
  9. linux系统中清空文件内容的三种方法
  10. 韩顺平 java 坦克大战_Tankgame 韩顺平版本的坦克大战,详细包括源代码,素材以及对应文件 Java Develop 263万源代码下载- www.pudn.com...
  11. 树莓派PI2编译天猫魔盘驱动,附编译好ko文件
  12. 第四代计算机cpu采用的超大规模集成电路,计算机一级试题a.doc
  13. 中国实验室玻璃器皿行业市场供需与战略研究报告
  14. vs2013界面内容_我在2013年阅读的内容
  15. TJOI 2015 弦论 题解
  16. 陕西宝鸡发现桃花水母 (组图)
  17. 20120814-虚拟串口VSPD的使用方法
  18. 酒醉之后你最思念谁?
  19. Java——Map集合
  20. 2022年了总有一款软件是你需要的,9款软件测评

热门文章

  1. C# 线程手册 第三章 使用线程
  2. MPLS原理之MPLS基本结构—Vecloud微云
  3. OpenCV神经网络ANN代码编译运行与解读(一)
  4. postgresql中自定义函数脚本的备份及恢复
  5. 今天收拾了个电脑抽屉,发现原来我是个有钱人
  6. [No0000C0]百度网盘真实地址解析(不用下载百度网盘)20170301
  7. 在WildFly中运行多个standalone模式的实例
  8. 控件View动态设置高度时会卡顿、速度慢的情况解决
  9. 解决Android中无法搜索联系人的问题
  10. java 观察者模式