草庐IT

ViewPager 和 FragmentPagerAdapter 中 Fragment 的 Android 生命周期管理

coder 2023-11-18 原文

我一直在努力找出在 FragmentActivity 中正确管理 Fragment 的方法。与 ViewPager是。在我详细介绍之前,我面临的问题的快速摘要如下:

我有一个 FragmentActivityViewPager . ViewPager使用自定义但非常简单 FragmentPagerAdapter .每个FragmentViewPager包含一个 ExpandableListView .我还有一个名为“刷新”的操作栏按钮。现在,让我们假设 ViewPager只有一个 Fragment . Activity 已创建,FragmentExpandableListView人口稠密(到目前为止一切顺利)。当点击刷新按钮时,FragmentActivity内的处理方法迭代 Fragments 的列表分配给 FragmentPagerAdapter 并调用 refresh()在每个 Fragment填充其 ListView。但是,当设备的方向发生变化(例如从纵向变为横向)时,Activity 会重新创建, fragment 也会重新创建。现在单击“刷新”按钮将遍历未初始化的 Fragments .

我知道我很含糊,尤其是没有示例代码,但请耐心等待。我从应用程序/Activity 的开始跟踪问题和方法调用如下:

  • FragmentActivity.onCreate()
  • FragmentActivity.setContentView()
  • FragmentActivity.createPagerFragments() <-- 这将创建一个="" fragment="" arraylist="" 并将它们分配给一个新的="" fragmentpageradapter,而后者又分配给="" viewpager。="">
  • Fragment.onAttach()
  • Fragment.onCreate() <-- 这里没什么特别的,只是调用了="" super="" 方法。="">
  • Fragment.onCreateView() <-- 这里也没什么特别的,只是夸大了布局="">
  • Fragment.onActivityCreated() <-- 这里也没有。="">
  • < 一切都好,这里的方向改变了="">>
  • FragmentActivity.onCreate()
  • Fragment.onAttach()
  • Fragment.onCreate()
  • FragmentActivity.setContentView()
  • FragmentActivity.createPagerFragments()
  • Fragment.onCreateView()
  • Fragment.onActivityCreated()
  • < 点击刷新按钮="">>
  • FragmentActivity.refresh() <-- 迭代="" #13="" 中新创建的="" fragments(不是这些由="" android="" 开发的!)。="">
  • < 崩溃:fragment="" 中="" mexpandablelistview="" 的="" nullpointerexception。="">>

  • 因此,在我看来,问题如下:
    当 Android 重新创建 FragmentActivity和它的 Views屏幕方向改变后(调用上面的#9-15),它会创建新的 Fragment状态恢复到原始状态的对象。但是,这些似乎完全由 FragmentManager 管理。 ,而不是通过 FragmentPagerAdapter .相比之下,当FragmentPagerAdapterFragments 一起重新创建在 Activity 的onCreate方法(见调用#13)Fragments分配给适配器的永远不会有他们的 Fragment.onCreate()Fragment.onCreateView()方法调用。因此,当调用 refresh() 方法时(参见 #17),该方法将迭代这些 Fragments尚未初始化的。因此,当他们尝试填充 ExpandableListView 时, View 的实例变量是 NULL .这是可以预料的,因为实例变量仅在 Fragment.onCreateView() 中分配永远不会被调用的方法 Fragments .

    所以我的问题是:如何正确地重新使用重新创建的(由 Android)Fragments在屏幕方向改变后以避免创建未初始化的新方向?我需要对它们有一个有效的引用,以便调用按需填充它们的 refresh() 方法。理想情况下,它们也应该分配给 FragmentPagerAdapter以及。

    我希望我已经清楚地描述了这个问题,我没有提供示例代码的原因是因为问题(可以看出)不是来自代码本身,而是来自相当不正确(似乎)的 Fragments 重新创建而不是重复使用。但是如果需要,我可以给你示例代码,我只是通过这种方式会更清楚。

    谢谢!

    最佳答案

    阅读内容很多,但在阅读了介绍和问题并体验了 FragmentStatePagerAdapter(类似于 FragmentPagerAdapter)之后,我可以告诉你:

    旋转后,您的适配器将自动连接旧 fragment 。因此,虽然正在重新创建 Activity 创建适配器,但 FragmentManager,它是全局的,它的实例保留 Activity 的重新创建将检测到新的 FragmentStatePagerAdapter 与相同的 ViewPager 组合并请求相同的 Fragment,并将简单地从 Fragment 的 BackStack 中获取它们。

    作为 Fragment 的设计者,您可以通过继续调用 Fragment.onAttach() 和 Fragment.onDetach() 来注意到这种行为。当 onAttach() 发生时,它要么创建 Fragment,要么在旋转后重用它。您应该能够通过使用回调 onRestoreRnstanceState() 来区分 Fragment 是旋转的。

    您将在日志中同时看到许多 onCreate() 和其他状态日志,因为 FragmentStatePagerAdapter 总是获取/创建最少 3 个 fragment (除非您将它们设置为只有 2 个或 1 个),因此在屏幕旋转后,3 个 fragment 也将从中重新附加背叠。

    我希望它有所帮助。

    关于ViewPager 和 FragmentPagerAdapter 中 Fragment 的 Android 生命周期管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20355127/

    有关ViewPager 和 FragmentPagerAdapter 中 Fragment 的 Android 生命周期管理的更多相关文章

    1. ruby - i18n Assets 管理/翻译 UI - 2

      我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

    2. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

      我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

    3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

      是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

    4. 安卓apk修改(Android反编译apk) - 2

      最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

    5. ruby - (Ruby || Python) 窗口管理器 - 2

      我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

    6. ruby-on-rails - 事件管理员和自定义方法 - 2

      这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

    7. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

      我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

    8. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

      文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

    9. ruby-on-rails - 使用用户或管理员模型和 Basecamp 样式子域设计登录 - 2

      我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica

    10. ruby-on-rails - 具有管理 namespace 的 Rails 3 中的 I18n - 2

      我正在根据Rails指南的建议开发Rails应用程序,以创建包含翻译的文件夹树和文件。我的文件夹树与此类似:|-defaults|---es.rb|---en.rb|-models|---book|-----es.rb|-----en.rb|-views|---defaults|-----es.rb|-----en.rb|---books|-----es.rb|-----en.rb|---users|-----es.rb|-----en.rb|---navigation|-----es.rb|-----en.rbconfig/locales/views/books/en.yml中的内容

    随机推荐