Fragment结合ViewPager之懒加载

什么是懒加载?为什么要用懒加载?###

1、什么是懒加载

懒加载就是当ViewPager和Fragment结合在一起使用时,Fragment呈现在用户面前时才加载数据,当其从未被呈现在用户面前时,不会执行加载数据的代码。这就是我所理解的懒加载。

2、为什么要用懒加载

ViewPager默认会预加载下一页,对于某些重量级的Fragment来说无疑会造成很大的开销,当然了,如果对于你来说这些开销是必要的,也不必无脑用懒加载。

背景简介

很多时候我们都会将ViewPager和Fragment结合在一起使用,因为Android给我们提供了非常便利的FragmentPageAdapter,而这个adapter实现起来非常简单:

public class TechFragmentPageAdapter extends FragmentPagerAdapter {private List<Fragment> fragmentList;public TechFragmentPageAdapter(FragmentManager fm, List<Fragment> fragmentList) {super(fm);this.fragmentList = fragmentList;}@Overridepublic Fragment getItem(int position) {return fragmentList.get(position);}@Overridepublic int getCount() {return fragmentList.size();}
}
复制代码

现在我们一般的Activity都是继承于AppCompatActivity,而这个activity可以

getSupportFragmentManager();
复制代码

那么在实现以上的adapter时我们只要传入我们的fragmentList就可以了。这样的adapter既看起来舒服,又好使。但是ViewPager默认会加载下一页,当你调用setOffscreenPageLimit(),并且将值设置为0,抱歉,没啥用,因为当你设置的值小于1的时候默认还是1。那么,这个时候就需要我们自己去实现懒加载了。

实现

实现懒加载的关键是在于以下两个方法:

/*** 文档对于这个方法的描述是:Set a hint to the system about whether this * fragment's UI is currently visible to the user.**/
getUserVisibleHint()
setUserVisibleHint(boolean isVisibleToUser)
复制代码

接下来让我通过一段Log来了解这段故事,因为代码结构比较简单,只放其中的一段代码上来,其他的,靠我们脑补就行了。

public class FirstFragment extends Fragment {private static final String TAG = "FirstFragment";@Overridepublic void onAttach(Context context) {Log.e(TAG, "onAttach");super.onAttach(context);}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {Log.e(TAG, "onCreate");super.onCreate(savedInstanceState);}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {Log.e(TAG, "onCreateView");return super.onCreateView(inflater, container, savedInstanceState);}@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {Log.e(TAG, "onActivityCreated");super.onActivityCreated(savedInstanceState);}@Overridepublic void onStart() {Log.e(TAG, "onStart");super.onStart();}@Overridepublic void onResume() {Log.e(TAG, "onResume");super.onResume();}@Overridepublic void onPause() {Log.e(TAG, "onPause");super.onPause();}@Overridepublic void onStop() {Log.e(TAG, "onStop");super.onStop();}@Overridepublic void onDestroyView() {Log.e(TAG, "onDestroyView");super.onDestroyView();}@Overridepublic void onDestroy() {Log.e(TAG, "onDestroy");super.onDestroy();}@Overridepublic void onDetach() {Log.e(TAG, "onDetach");super.onDetach();}@Overridepublic boolean getUserVisibleHint() {Log.e(TAG, "getUserVisibleHint");return super.getUserVisibleHint();}@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);Log.e(TAG, "setUserVisibleHint:" + isVisibleToUser);}
}复制代码

非常简单的一个Fragment,我只是在其中的各个方法中加入了Log这个操作而已,为了方便查看我使用了e这个级别的日志。类似的Fragment还有SecondFragment和ThirdFragment。当我使用FragmentPagerAdapter和ViewPager的时候,他们的Log输出如下:

首先和我们预料的一样,ViewPager的确有加载下一页的特性,然后我们滑动到第二页查看Log。

我们可以发现,当我们滑动到第二页时,第三页开始预加载,而且第二页的setUserVisibleHint中的值已经被置为了true。也就是说当前页面可见时,我们调用getUserVisibleHint()的值是true。那么我们可以根据这个特性去实现懒加载:

** 当前页面不可见,但是ViewPager预加载的时候,我们判断当前页面是否可见,不可见则不进行加载数据的操作,仅仅做布局初始化的工作。在当前页面变为可用的时候,我们调用加载数据的方法,那么数据便在ViewPager滑动到当前页面的时候开始加载了。**

以下是我封装的代码,我封装无力,各位如果觉得可以便自取,如果觉得不行可以自己改进~

package com.lauren.simplenews.news.widget;import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;/*** Created by Luo_xiasuhuei321@163.com on 2016/8/29.** 实现懒加载的Fragment*/
public abstract class BaseLazyFragment extends Fragment {protected View mRootView;protected Context mContext;protected boolean isVisible;private boolean isPrepared;private boolean isFirst = true;//--------------------system method callback------------------------//@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);isPrepared = true;initPrepare();}@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);if(getUserVisibleHint()){isVisible = true;lazyLoad();}else{isVisible = false;onInvisible();}}@Overridepublic void onResume() {super.onResume();if(getUserVisibleHint()){setUserVisibleHint(true);}}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = getActivity();}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {if(mRootView == null){mRootView = initView(inflater,container,savedInstanceState);}return mRootView;}//--------------------------------method---------------------------///*** 懒加载*/protected void lazyLoad(){if(!isPrepared || !isVisible || !isFirst){return;}initData();isFirst = false;}//--------------------------abstract method------------------------///*** 在onActivityCreated中调用的方法,可以用来进行初始化操作。*/protected abstract void initPrepare();/*** fragment被设置为不可见时调用*/protected abstract void onInvisible();/*** 这里获取数据,刷新界面*/protected abstract void initData();/*** 初始化布局,请不要把耗时操作放在这个方法里,这个方法用来提供一个* 基本的布局而非一个完整的布局,以免ViewPager预加载消耗大量的资源。*/protected abstract View initView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState);
}
复制代码

###后话### 最近我搭建了自己的个人博客,虽然今天(9.2)没时间完善了,但是以后有空我会完善一下的。而且有些文章我也不会再简书更新……比如我想把我的java回炉重造一下……但是有关java的这些东西不怎么想放到简书上,还是放到我自己的小窝里~

最后附上链接吧:https://xiasuhuei321.github.io 恩,域名暂时没买,先就这么用着吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WCF和webservice的区别

微软论坛的斑竹回答如下&#xff1a; 脑内&#xff1a;果然是高大上啊 1.WebService&#xff1a;严格来说是行业标准&#xff0c;不是技术&#xff0c;使用XML扩展标记语言来表示数据&#xff08;这个是夸语言和平台的关键&#xff09;。微 软的Web服务实现称为ASP.NET Web Ser…

职场不得不明白的十大定律

帕金森定律 美国著名历史学家诺斯古德•帕金森通过长期调查研究&#xff0c;写了一本名叫《帕金森定律》的书&#xff0c;他在书中阐述了机构人员膨胀的原因及后果&#xff1a;一个不称职的官员&#xff0c;可能有三条出路。第一是申请退职&#xff0c;把位子让给能干的人&am…

php控制器教程,laravel基础教程 -- 控制器

HTTP 控制器简介控制器允许你将相应的路由业务逻辑封装在控制器类中进行有效的管理&#xff0c;这样你不必将所有的路由逻辑集中到routes.php文件中&#xff0c;导致代码的臃肿与难以维护。所有的控制器类都被存储在app/Http/Controllers目录中.基本控制器一个基本的控制器应该…

org.apache.jasper.JasperException: Unable to compile class for JSP:

报错信息&#xff1a; org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream cannot be resolved. It is indirectly referenced from required .class filesSt…

i++和++i

关于自增自减运算&#xff0c;很多书籍没有把问题讲清楚,在C语言里是这样的&#xff1a; 1.后置运算&#xff1a;k表示先运算&#xff0c;后自加。 意思是遇到k了&#xff0c;我先把当前的k的值拿来参加运算&#xff0c;后面再去管它的自加。 那么&#xff0c;“后面”后到什么…

什么样的项目经历会让面试官眼前一亮

很多同学都问过我类似的问题&#xff1a; 咱们《C语言也能干大事》中讲的自己动手写windows优化大师、自己动手写计算器等东西只是写着玩的小玩具而已&#xff0c;这些能用来以后找工作时写到简历中的作品吗&#xff1f;看别人的简历写的“图书管理系统”、“教务选课系统”多有…

matlab采样频谱,Matlab对采样数据进行频谱分析

使用Matlab对采样数据进行频谱分析1、采样数据导入Matlab采样数据的导入至少有三种方法。第一就是手动将数据整理成Matlab支持的格式&#xff0c;这种方法仅适用于数据量比较小的采样。第二种方法是使用Matlab的可视化交互操作&#xff0c;具体操作步骤为&#xff1a;File --&g…

链表和顺序表的一些区别

顺序表与链表是非常基本的数据结构&#xff0c;它们可以被统称为线性表。 线性表&#xff08;Linear List&#xff09;是由 n&#xff08;n≥0&#xff09;个数据元素&#xff08;结点&#xff09;a[0]&#xff0c;a[1]&#xff0c;a[2]…&#xff0c;a[n-1] 组成的有限序列。…

ANCS推送简介

总体原理 ANCS通过蓝牙BLE 4.0实现&#xff0c;仅支持iPhone 4S及以上且系统版本在IOS 7以上的手机&#xff0c;同时在外设端需要支持蓝牙4.0协议。 1、外设端进行广播&#xff0c;手机打开蓝牙&#xff0c;搜索外设&#xff0c;连接外设&#xff0c;之后进行绑定&#xff08;这…

好记性不如烂笔头,记录几个常用的Linux操作

作者&#xff1a;老王Shell公共函数库Linux系统里有一些公共的Shell函数库可供使用&#xff0c;最重要的是/etc/rc.d/init.d/functions&#xff0c;在/etc/init.d目录下有很多脚本都用到了这个函数库&#xff0c;里面提供了很多有用的方法&#xff0c;比如&#xff1a;killproc…

用matlab简单电路模型,基于MATLAB的电路模型仿真应用

基于MATLAB的电路模型仿真应用实验指导书一、实验目的1、掌握采用M文件及SIMULINK对电路进行仿真的方法。2、熟悉POWERSYSTEM BLOCKSET 模块集的调用、设置方法。3&#xff0e;进一步熟悉M脚本文件编写的方法和技巧。二、实验原理1、通过M文件实现电路仿真的一般仿真步骤为&…

春节期间小游戏同时在线人数最高达2800万人/小时

微信官方发布2018年春节期间微信数据报告&#xff1a;除夕至初五&#xff0c;总共有2,297亿条微信消息&#xff0c;28亿条微信朋友圈成功发出&#xff0c;音视频通话总时长175亿乙分钟。其中&#xff0c;90后用广的消息发送量占总量的42.5%&#xff0c;80后用户25.9%&#xff0…

C语言中* 和

&x是对x变量取地址&#xff0c;也就是返回的是x的地址。 int *i;这里面的*说明变量i是一个指针&#xff0c;存的是一个地址。 而 *i整体代表的是一个数值&#xff0c;例如可以int *i 5 这里整体的*i代表的是5&#xff0c;而i代表的是这个值存储的地址

餐馆的故事-浅析职责链模式

我们在餐馆吃饭的时候&#xff0c;一般都是在拿到菜单后&#xff0c;选择喜欢的菜&#xff0c;然后通知服务员。服务员会将我们的定单交给大厨&#xff0c;大厨可能会亲自去做这道菜&#xff0c;也可能安排给小厨来做&#xff0c;总之&#xff0c;我们不用担心他们没有人做菜&a…

JDBC数据对象存储

一&#xff1a;将查询的结果生成对象&#xff0c;储存在数组中。 1 package day31;2 3 import java.sql.Connection;4 import java.sql.PreparedStatement;5 import java.sql.ResultSet;6 import java.sql.SQLException;7 import java.util.ArrayList;8 9 public class java_ob…

个人工作13年的一些人生真实领悟

此文不定期的更新&#xff0c;想起来就写一些&#xff0c;我都忘了我曾经会过什么了。你可能会在许多的文章里看到类似的&#xff0c;但这些是我个人的真实体会。 1 技术服从于业务 此问题以前的一个文章提过&#xff0c;不再多说。 适用于大多数对技术的盲目崇拜者。在绝大…

matlab非齐次方程组的通解,用matlab求非齐次线性方程组的通解?

先向大家介绍一下非齐次线性方程组。所谓非齐次线性方程组就是方程组等号右边的常数项不全为零的线性方程组。全部等于零时&#xff0c;就称为齐次线性方程组。下面我们就讲解一下如何利用matlab快速求非齐次线性方程组的通解。工具/材料matlab电脑操作方法01线性方程组Axb的求…

Linux 终端仿真程序Putty

PuTTY是一个Telnet、SSH、rlogin、纯TCP以及串行接口连接软件。较早的版本仅支持Windows平台&#xff0c;现在的版本中开始支持各类Unix平台。 用linux作为桌面系统&#xff0c;身为工程师很多时候需要通过Telnet、SSH协议进行远程管理&#xff0c;通过串口进行设备配置。Putty…

Mysql 数据库水平分表 存储过程

数据库存储量达到一定程度的时候&#xff0c;就需要进行分表以减轻检索的消耗。 常用的分表方式包括水平和垂直分表。本次进行的是按照uid进行水平分表。 ##分表思路&#xff1a; 水平分表平均的将数据按照特定方式分配到多个表中。理论上每个表的访问频次和数据量都是同一水平…

中国架构师,名符其实有多少?

先说一下读后感&#xff1a;我前段时间去过几个公司面试架构师&#xff0c;要求还是蛮高的&#xff0c;要熟悉大数据量处理&#xff0c;要熟悉高并发&#xff0c;要熟悉XX体系架构&#xff0c;要能在关键技术上实现突破。总之&#xff0c;架构错了&#xff0c;就啥都错了。呵呵…