pagerAdapter 与FragmentPagerAdapter的区别

转自:http://blog.csdn.net/dreamzml/article/details/9951577

ViewPager

ViewPager 如其名所述,是负责翻页的一个 View。准确说是一个 ViewGroup,包含多个 View 页,在手指横向滑动屏幕时,其负责对 View 进行切换。为了生成这些 View 页,需要提供一个 PagerAdapter 来进行和数据绑定以及生成最终的 View 页。
  • setAdapter()
    • ViewPager 通过 setAdapter() 来建立与 PagerAdapter 的联系。这个联系是双向的,一方面,ViewPager 会拥有 PagerAdapter 对象,从而可以在需要时调用 PagerAdapter 的方法;另一方面,ViewPager 会在 setAdapter() 中调用 PagerAdapter 的 registerDataSetObserver() 方法,注册一个自己生成的 PagerObserver 对象,从而在 PagerAdapter 有所需要时(如 notifyDataSetChanged() 或 notifyDataSetInvalidated() 时),可以调用 Observer 的 onChanged() 或 onInvalidated() 方法,从而实现 PagerAdapter 向 ViewPager 方向发送信息。
  • dataSetChanged()
    • 在 PagerObserver.onChanged(),以及 PagerObserver.onInvalide() 中被调用。因此当 PagerAdapter.notifyDataSetChanged() 被触发时,ViewPager.dataSetChanged() 也可以被触发。该函数将使用 getItemPosition() 的返回值来进行判断,如果为 POSITION_UNCHANGED,则什么都不做;如果为 POSITION_NONE,则调用 PagerAdapter.destroyItem() 来去掉该对象,并设置为需要刷新 (needPopulate = true) 以便触发 PagerAdapter.instantiateItem() 来生成新的对象。

PagerAdapter

PageAdapter 是 ViewPager 的支持者,ViewPager 将调用它来取得所需显示的页,而 PageAdapter 也会在数据变化时,通知 ViewPager。这个类也是FragmentPagerAdapter 以及 FragmentStatePagerAdapter 的基类。如果继承自该类,至少需要实现 instantiateItem(), destroyItem(), getCount() 以及 isViewFromObject()。

  • getItemPosition()
    • 该函数用以返回给定对象的位置,给定对象是由 instantiateItem() 的返回值。
    • 在 ViewPager.dataSetChanged() 中将对该函数的返回值进行判断,以决定是否最终触发 PagerAdapter.instantiateItem() 函数。
    • 在 PagerAdapter 中的实现是直接传回 POSITION_UNCHANGED。如果该函数不被重载,则会一直返回 POSITION_UNCHANGED,从而导致 ViewPager.dataSetChanged() 被调用时,认为不必触发 PagerAdapter.instantiateItem()。很多人因为没有重载该函数,而导致调用
       PagerAdapter.notifyDataSetChanged() 后,什么都没有发生。
  • instantiateItem()
    • 在每次 ViewPager 需要一个用以显示的 Object 的时候,该函数都会被 ViewPager.addNewItem() 调用。
  • notifyDataSetChanged()
    • 在数据集发生变化的时候,一般 Activity 会调用 PagerAdapter.notifyDataSetChanged(),以通知 PagerAdapter,而 PagerAdapter 则会通知在自己这里注册过的所有 DataSetObserver。其中之一就是在 ViewPager.setAdapter() 中注册过的 PageObserver。PageObserver 则进而调用 ViewPager.dataSetChanged(),从而导致 ViewPager 开始触发更新其内含 View 的操作。

FragmentPagerAdapter

FragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。如文档所述,该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。FragmentPagerAdapter 重载实现了几个必须的函数,因此来自 PagerAdapter 的函数,我们只需要实现 getCount(),即可。且,由于 FragmentPagerAdapter.instantiateItem() 的实现中,调用了一个新增的虚函数 getItem(),因此,我们还至少需要实现一个 getItem()。因此,总体上来说,相对于继承自 PagerAdapter,更方便一些。
  • getItem()
    • 该类中新增的一个虚函数。函数的目的为生成新的 Fragment 对象。重载该函数时需要注意这一点。在需要时,该函数将被 instantiateItem() 所调用。
    • 如果需要向 Fragment 对象传递相对静态的数据时,我们一般通过 Fragment.setArguments() 来进行,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。
    • 如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么,这部分代码不适合放到 getItem() 中。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么很多人发现调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。
  • instantiateItem()
    • 函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。
    • FragmentPagerAdapter 会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法
    • 如果需要在生成 Fragment 对象后,将数据集中的一些数据传递给该 Fragment,这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用 FragmentPagerAdapter.instantiateItem() 取得该函数返回 Fragment 对象,然后,我们该 Fragment 对象中对应的方法,将数据传递过去,然后返回该对象。
    • 否则,如果将这部分传递数据的代码放到 getItem()中,在 PagerAdapter.notifyDataSetChanged() 后,这部分数据设置代码将不会被调用。
  • destroyItem()
    • 该函数被调用后,会对 Fragment 进行 FragmentTransaction.detach()。这里不是 remove(),只是 detach(),因此 Fragment 还在 FragmentManager 管理中,Fragment 所占用的资源不会被释放。

FragmentStatePagerAdapter

FragmentStatePagerAdapter 和前面的 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是,和 FragmentPagerAdapter 不一样的是,正如其类名中的 'State' 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,生成新的页面(就像 ListView 的实现一样)。这么实现的好处就是当拥有大量的页面时,不必在内存中占用大量的内存。
  • getItem()
    • 一个该类中新增的虚函数。
    • 函数的目的为生成新的 Fragment 对象。
    • Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。
    • 由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。
  • instantiateItem()
    • 除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。
    • FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。
  • destroyItem()
    • 将 Fragment 移除,即调用 FragmentTransaction.remove(),并释放其资源。

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

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

相关文章

2015蓝桥杯省赛---java---A---2(星系炸弹)

题目描述 思路分析 方案一 方案二 package TEST;import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;class Main{public static void main(String[] args) {SimpleDateFormat dateFormat new SimpleDateFormat("yyyy-MM-dd");…

NuGet社区使用体验调查

Nuget 是我们使用.NET Core的一项基础设施,针对国内访问NuGet服务器速度不稳定的问题我们希望通过收集一些来自用户的反馈来改善社区使用NuGet的体验。恳请您花2-3分钟时间完成以下的问题,我们会非常重视您的反馈。当我们收集完成所有的问卷,…

在护卫神上部署javaWeb项目,已经测试通过

以前一直在护卫神上部署PHP项目,今天忽然来了需求是部署javaWeb项目,刚开始一脸蒙蔽,后来发现也不是很难。那么接下来我们看看怎么在护卫神上部署java项目: 第一步:打开护卫神,在护卫神中添加一个网站&…

为什么选择微服务架构?如何取舍?

转载自 为什么选择微服务架构?如何取舍? 微服务是什么 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成…

三星系统和鸿蒙系统,又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!...

又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!前段时间华为正式发布了鸿蒙系统,这个系统可以说是期待已久了,在华为处于禁令时期时,鸿蒙被认为是替代安卓的操作系统。在鸿蒙发布后&#xff0…

android之视频直播与播放Vitamio

直播APP l 直播原理 直播本质:实时推送/拉取过来的音视频数据 直播相关的协议: l RTMP(实时消息的传输协议) RTMP协议是一个互联网TCP/IP五层体系结构中的应用层协议 RTMP协议可以用来推送又可以用来直播 RTMP协议中基本的…

从真实项目中抠出来的设计模式——第一篇:策略模式

有时候因为种种原因导致我们会写出很多丑陋的代码,比如赶工时,短暂性的偷懒,不会设计模式等等导致代码沉积,一个cs上万行代码这样场景是有发生, 当然这里也包括我。。。所以时间充裕一点之后就想重构一下,…

jquery实现单击div切换背景,再次单击回到原来样式

首先来看看效果图: 1.这是默认的的div样式: 2.当我们单击第一个div时的样式: 3.当我们再次单击第一个div时的样式: 如果你需要的效果是这样的,那么请您继续往下面看,如果不是,您也可以看看实…

Java进阶之对象克隆(复制)

转载自 Java进阶之对象克隆(复制) 假如说你想复制一个简单变量。很简单: int apples 5; int pears apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但…

wxapkg的html反编译,wxapkg反编译工具包

软件简介 Soft IntroductionWechat App微信小程序反编译解包工具wxapkg及相关文件(.wxss,.json,.wxs,.wxml)还原工具。wxappUnpacker版本V0.3,当前功能如下(分包功能尚未完成!)将app-config.json中的内容拆分到各个文件对应的 .json和app.json , 并通过搜…

如何下载网页中的视频成mp4格式

1.在生活中,我们经常在网页上看到某个视频之后想要下载下来,可是,网上大部分的视频都在几大播放器所占领,比如爱奇艺、优酷、腾讯等等,当你在这些上面下载的时候会发现先要让你下载播放器,才能下载视频。这…

微软CNTK 2.0版本发布,支持C#

微软 CNTK 2.0 版本今天正式发布。 CNTK(Cognitive Toolkit)是微软的深度学习工具包,可以帮助企业加速图像和语音识别进程。有了今天的更新,企业可以在本地或云端结合 Azure GPU 使用 CNTK了。 伴随着今天的新版本发布&#xff0c…

Android碎片Fragment详讲(1)

Fragment Fragment创建的步骤 1、 继承fragment一定是V4包下的 2、 有且只有一个无参的构造方法 3、 如果Fragment需要显示界面,需要重写onCreateView方法 4、 指定布局资源,或者创建布局,返回即可 静态创建frag…

关于人脸和指纹识别共同交流方案

尊敬的各位朋友,各位粉丝: 非常感谢各位能从博客看到关于人脸识别的文章给我的评论以及点赞,也有好多粉丝从博客中直接加我的QQ,找我要js和jar包,我也大部分都给了。还有的找我要源码!!&#xf…

这些BATJ必考的Java面试题,你都懂了吗?

转载自 这些BATJ必考的Java面试题,你都懂了吗? 题目一 请对比 Exception 和 Error,另外,运行时异常与一般异常有什么区别? 考点分析: 分析 Exception 和 Error 的区别,是从概念角度考察了…

计算机玩游戏特别卡,Win7电脑游戏卡顿怎么办 win7玩游戏卡如何解决

很多人都喜欢在win7系统中玩游戏,而在玩游戏的时候经常会碰到一些故障,比如有很多用户反映的游戏卡顿、玩游戏太卡,这让很多游戏玩家很是苦恼,那么Win7电脑游戏卡顿怎么办呢?下面给大家介绍一下win7玩游戏卡的解决方法…

在IIS上部署你的ASP.NET Core项目

概述 与ASP.NET时代不同,ASP.NET Core不再是由IIS工作进程(w3wp.exe)托管,而是使用自托管Web服务器(Kestrel)运行,IIS则是作为反向代理的角色转发请求到Kestrel不同端口的ASP.NET Core程序中&a…

2020蓝桥杯省赛---java---A---2(既分数组)

题目描述 代码实现 package TEST;public class Main {public static void main(String[] args) {int ans 0;for(int i1; i<2020; i)for(int j1; j<2020; j) // if(j>i){{if(gcd(i, j) 1) ans;} // }else { // if(gcd(i, j) …

第一章数据库系统基础

第一章数据库系统基础 一、数据库&#xff1a;存储数据的仓库 二、数据库能够做什么&#xff1a; 1.存储大量的数据&#xff0c;方便检索和访问。 2.保持数据的信息一致、完整 3.共享和安全 4.通过组合分析&#xff0c;产生新的有用信息。 三、应用程序和数据库的关系 应用程序…

微信消息提醒与消息数字提示之BadgeView

微信消息提醒与消息数字提示之BadgeView BadgeView 一个可以自由定制外观、支持拖拽消除的 MaterialDesign 风格 Android BadgeView。 GitHub地址&#xff1a;https://github.com/stefanjauker/BadgeView 代码&#xff1a; MainActivity&#xff1a; package com.example.jash.…