Android开发之多Fragment切换优化(解决切换卡顿)

2023-11-05

我想刚刚接触安卓的同学或许会这么写:

FragmentManager     fragmentManager=getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.add(ViewId,fragment);// 或者fragmentTransaction.replace(ViewId,fragment);
fragmentTransaction.commit();

基础更好一点的同学会用show和hide方法

  FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(new FirstFragment())
        .show(new SecondFragment())
        .commit();

诚然这两种都可以切换Fragment,但是面对用户大量点击来回切换,或者你的Fragment本来就很多,每次都这样操作,那么很快你的应用就会OOM,就算不崩那也会异常的卡顿!so why?

当我们replace时发生了以下的生命周期:

 

想想看每次都replace一下!!这世界会有多美好!!!那么问题出在哪?回过头看看代码就会发现每次在add/replace或者show/hide都会new 一个新的实例,这就是致命原因!!!!!

废话少说,开始优化


方案一:

预加载模式:

//首先需要先实例好三个全局Fragment

FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment, FirstFragment.getInstance());
ft.add(R.id.fragment, SecondFragment.getInstance());
ft.add(R.id.fragment, ThirdFragment.getInstance());
ft.hide(SecondFragment.getInstance());
ft.hide(ThirdFragment.getInstance());
ft.commit();

在加载第一个Fragment时就把全部Fragment加载好,下次使用直接调用如:

FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(FirstFragment.getInstance())
        .show(SecondFragment.getInstance())
        .commit();

是不是总觉怪怪的,虽然比之前的代码好,但是这种做法很Java,当然需要预加载的朋友依然是不二之选!!!

那有没有更好的方法呢?答案是肯定的

方案二:

动态加载模式:

 

 

//首先需要先实例好n个全局Fragment

//private  Fragment  currentFragment=new Fragment();(全局)

private  FragmentTransaction switchFragment(Fragment targetFragment) {

   FragmentTransaction transaction = getSupportFragmentManager()
           .beginTransaction();
   if (!targetFragment.isAdded()) {
       //第一次使用switchFragment()时currentFragment为null,所以要判断一下
       if (currentFragment != null) {
           transaction.hide(currentFragment);
           }
       transaction.add(R.id.fragment, targetFragment,targetFragment.getClass().getName());

       } else {
           transaction
                   .hide(currentFragment)
                   .show(targetFragment);


       }
       currentFragment = targetFragment;
      return   transaction;
   }

在点击切换Fragment时:

@Override
public void onTabSelected(@IdRes int tabId) {

        if (tabId == R.id.tab_one){

            switchFragment(first).commit();

        }
        if (tabId == R.id.tab_two){
            switchFragment(second).commit();
        }
        if (tabId == R.id.tab_three){
            switchFragment(third).commit();
        }
    }

现在你的Fragment无论怎么切都不会出现卡顿了,因为你的所有Fragment只会被实例化一次!实例一次的Fragment会被存入内存中,下次切换会判断内存中是否含有要切换的Fragment,如果有就直接复用,没有就add一个新的!优化大法完成!

外番


WHAT?等等!只实例一次,那我的Fragment里的数据要更新怎么办?我的回答是——软件关了再次重启!

 

要是这样,这样的软件真的要逆天了!好在官方提供了onHiddenChanged方法,每次切换hide或者show时该方法会被执行,可以在这里面更新数据!

 

//此方法在Fragment中

@Override
public void onHiddenChanged(boolean hidden) {
   super.onHiddenChanged(hidden);
   if (hidden){
      //Fragment隐藏时调用
   }else {
       //Fragment显示时调用
   }

}

此方法是不是比每次add或replace更新数据执行一大坨的生命周期要优雅的多的多!

 

GitHub地址:FragmentDemo (欢迎 fork 和 star)

注:提醒小白(老手请忽略)

此demo只供fragment理解,此样例app的业务逻辑建议ViewPager+Fragment或者其他。。。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android开发之多Fragment切换优化(解决切换卡顿) 的相关文章

  • 在片段中使用上下文的最佳方式

    我在我的应用程序中使用片段 我创建了一个名为 BaseFragment 的父类 所有其他片段都扩展了此 Basefrgment 下面是此 Basefragment 的片段 基础片段 java public class BaseFragmen
  • Android 应用程序在使用 Fragments 和 ViewPager 一段时间后崩溃

    当我尝试恢复我的片段时 我的 Android 应用程序崩溃了 我没有向我尝试恢复的包添加任何自定义变量 这都是默认的 我正在使用 Fragments 和 ViewPager 请参阅下面我的代码片段 public static class M
  • 在片段中初始化字体

    我有这一行 Typeface font Typeface createFromAsset getAssets fonts Delius Regular ttf but the getAssets 参数似乎带来了一些错误 它带有可怕的红线下划
  • 如何缓存片段视图

    我想缓存一个片段视图 我的活动有可滑动的选项卡 每个选项卡调用不同的片段 但是 当我在选项卡之间滑动时 由于片段视图被破坏 在滑动操作期间会重建 转换似乎相当慢 有谁知道如何缓存每个片段的视图以防止此问题 我使用库支持 v4 和 api 1
  • 使用带有新值的片段多次并进行后台维护

    我正在制作一个应用程序滑动菜单 and tab在底部 整个应用程序是fragment基于 我面临一些我正在使用的问题片段A然后点击一个按钮并转到片段B in 片段B有一个按钮 点击这个按钮片段A将用新值更新 等等 意味着应该发生从 A gt
  • 导航组件防止在后按时重新创建片段

    我在项目中使用 Jetpack 导航组件 其中包含单个活动和一些片段 我有一个带有从服务器端填充的列表的片段 我打电话getDataFromServer on the onViewCreated然后 当用户单击某个项目时 会显示一个新片段
  • 当用户“滑出”viewpager 片段时运行代码?

    我需要检测用户何时从我的片段之一滑入和滑出 我尝试了 onPause 但似乎应用程序在滑到相邻屏幕时没有暂停 当将两个屏幕移开时它会被破坏 如果可能的话 我想从片段本身执行此操作 因为我正在动态更改片段 并且某些代码仅在存在某个片段时才有用
  • 当路径包含 url 片段时,如何在 Web 浏览器中打开本地 html 文件

    我正在尝试通过以下方法打开网络浏览器 然而 当浏览器打开 url 文件路径时 片段片段被破坏 从 anchorName 到 23anchorName 这似乎没有得到处理 所以基本上 文件打开但不会跳转到文档中的适当位置 有谁知道如何打开文件
  • 如何在屏幕旋转后禁用/避免片段自定义动画

    我刚刚发现 每次在片段上 setRetainInstance true 时 它都会按预期工作 保留片段数据 但这会导致片段的自定义动画在屏幕旋转后再次执行 有没有办法避免 禁用屏幕旋转时的这些动画 该片段是使用以下动画创建的 setCust
  • 如何将列表视图放入片段中

    如何将列表视图放入片段中 我使用带有固定选项卡的默认项目设置 它似乎不起作用 我的应用程序崩溃了 主要活动 import java util ArrayList import java util HashMap import java ut
  • 如何在 XML 布局中添加片段

    我有一个布局 其中包含一个片段 如下所示
  • Android Fragment 中的 EditText 值不刷新

    我正在使用Viewpager在 3 之间切换fragments 一切工作正常 除了第二个选项卡的刷新 或fragment 在这个选项卡中 我有一张图片 一些静态的Textviews 一些动态TextViews还有一些EditText fie
  • 如何:片段内的gridview?

    我想创建一个像 android market 一样的 gridview 我想用互联网上数据库中的图像填充它 它需要与 androidv4 support 一起使用 因为我想运行 2 2 直到 4 0 有人说 在4 0之前不可能创建gridv
  • Recyclerview 未更新新数据

    嗨 大家好 我有一个片段RecyclerView在里面 那RecyclerView由 Firebase DatabaseReference 对象填充 并在该引用上添加了一个 ValueListener 如下所示 public View on
  • 将工具栏设置为片段中的操作栏

    我想将我的工具栏设置为操作栏 但由于您的工具栏是布局元素 因此它必须位于您的布局中 现在我的布局在我的片段中 我在布局中添加了工具栏 并在片段中调用它 Toolbar Toolbar toolbar Toolbar getActivity
  • SupportMapFragment 地图为空

    我使用以下代码在 Xamarin Android 中显示地图 private SupportMapFragment mapFragment private GoogleMap map protected override void OnCr
  • 如何在 Fragment 中使用 onNewIntent(Intent Intent) 方法?

    我正在尝试从我的设备使用 NFC 硬件 但是 问题是当我注册 Activity 来接收 Intent 时 PendingIntent pendingIntent PendingIntent getActivity this 0 new In
  • 从底部工作表对话框片段中获取值

    我从片段A开始bottomSheetDialogFragment 我想从该bottomSheetDialogFragment中选择日期 然后将其设置在片段A中 选择日期已经完成 我只想将其获取到片段A中以在某些字段中设置它 我怎样才能得到这
  • Android 和 Google 地图内部片段以及其他控件和 viewpager

    我是android编程新手 我有一个带有 3 个页面 片段 的小应用程序 使用 pageradapter 和 viewpager 在它们之间滑动 其中一个页面包含复选框 和其他控件 和地图 我的问题是程序在启动时崩溃 Fragment co
  • Android 中的 Fragment-Fragment 通信

    我在Android编程方面处于初级水平 所以我需要你真诚的帮助 请任何人帮助我 我正在尝试使用片段构建滑动用户界面 所以我真正的疑问是 我有一个Fragment say FragmentA 它有一个TextView and Button在其

随机推荐

  • Error: 'C:\Keil\C51\BIN\SiC8051F.dll' not found 解决办法

    Error C Keil C51 BIN SiC8051F dll not found 解决办法 将C Keil UV3文件加下的两个文件USBHID dll uv3 cdb拷贝到C Keil UV4下
  • kali2021.2 安装及parallels tools

    看到网上十分零碎的安装方法 这里汇总了一下 经测试已成功 https www wolai com ckwalter s1Y51qyJDu7T4jv5hgdzB8 theme dark
  • 将代码复制到word里保留格式_如何让word中代码更美观

    转载 知乎 大块小屋 原文链接 https zhuanlan zhihu com p 108483150 写论文遇到最头大的事情 就是在word中插入代码时 格式全乱了 非常不美观 怎么又快又美的在word中插入代码 怎么让word中的代码
  • Linux下的多进程编程初步(转载)

    最近在学习linux环境高级编程 多进程编程算是编程中的最重要的一个部分了 本文让我学习和明白了很多 所以转载过来 让更多想多线程编程的人学习 只有顶到首页才能让更多的人学习 文章摘要 多线程程序设计的概念早在六十年代就被提出 但直到八十年
  • Tomcat启动乱码问题解决

    Tomcat 控制台UTF 8乱码问题 1 修改cmd的编码格式 快捷键win R打开运行程序 输入regedit打开注册表 找到以下路劲并且修改 HKEY LOCAL MACHINE SOFTWARE Microsoft Command
  • list怎么删除元素和ConcurrentModificationException

    当面试官 怎么删除list里面的元素 我 用for循环 活着迭代器 举例 循环 迭代器 看出什么问题了吗 对同一个集合遍历的不能删除 怎么解决 1 拷贝一份 一个用来遍历 一个用来删除 2 不用list的remove方法 用迭代器的remo
  • 【马士兵】Python基础--12

    Python基础 12 文章目录 Python基础 12 字符串比较 字符串切片 格式化字符串 字符串的编码与解码 知识点总结 字符串比较 print apple gt app print aanan gt banan print ord
  • RabbitMQ消息队列的总结

    什么是消息队列 MQ全称为MessageQueue 消息队列 MQ 是一种应用程序对应用程序的通信方法 应用程序通过写和检索出入列队的针对应用程序的数据 消息 来通信 而无需专用连接来链接它们 消息传递指的是程序之间通过在消息中发送数据进行
  • Java 高级篇:JVM 垃圾回收机制

    Java 语言的一大优势在于其具有自动垃圾回收 Garbage Collection GC 机制 让开发者无需关心内存的分配与释放 本文将详细解析 JVM Java Virtual Machine 中的垃圾回收机制 带你深入了解 GC 如何
  • 深度学习和语音系列教程 5-100:求共振峰

    文章目录 1 基音频率 1 1 基音频率的查看 2 共振峰的获取 2 1 倒谱法求共振峰 2 2 测试结果 2 3 共振峰位置坐标 2 4 多种情况下的共振峰测试 1 基音频率 1 1 基音频率的查看 基音频率就是发浊音时 气流通过声门使声
  • 在此计算机上运行应用程序不可选,win10提示此应用无法在你的电脑上运行若要找到适用怎么解决...

    最近有朋友问小编win10提示此应用无法在你的电脑上运行若要找到适用于你的电脑的版本 请咨询软件发布者应该怎么办 对于这样的问题 相信很多朋友都遇到过了 有时候我们经常会遇到这种情况 例如在win10系统中打开excel就可能会遇到这个错误
  • windows10清理鼠标右键菜单

    windows10清理鼠标右键菜单 文章目录 windows10清理鼠标右键菜单 前言 一 右键菜单管理 二 使用步骤 1 打开软件 2 选择不显示的菜单 效果 前言 系统右键菜单过长 挺烦人的 一般网上给出的答案都是修改注册表 对于小白来
  • 互联网世界的 “人工智能”——探秘 “深度学习” 的前世今生

    编者按 本文来自 流浪汉 投稿 ZhangLumin 一个在硅谷工作的码农 有机器学习背景 平常对产品方面很有兴趣 最近一段时间里 Facebook Google Yahoo 百度等各大公司都在尝试将深度学习 deep learning 算
  • 位图--排序

    位图使用基本情况 一个字节有8位 假设第0位表示0 第1位表示1 那么一个字节就可以表示8个数字 整数序列 0 1 4 7 在位序列中表示为10010011 左边第一位为低位 表示有效数字0 位序列如何表示 Java 整形int 用4个字节
  • java中重写父类方法加不加@Override

    java中重写父类方法加不加 Override 这个是我在刚学习java时遇到的问题 希望能给像我一样的新手学习时带来帮助 如有错误请指正 谢谢 class Father public String name public int age
  • python print带颜色乱码无效

    乱码了 那么导入库 并且进行init 即可 import colorama colorama init autoreset True print 033 1 31 40m 测试 print 033 1 32 41m 测试 print 033
  • “模块计算机类型“x64”与目标计算机类型“X86”冲突解决方案

    最近在编译一款开源软件的时候 遇到了 模块计算机类型 x64 与目标计算机类型 X86 冲突的问题 网上查了好多资料 都是配置 链接器 高级 目标计算机 和选择X64平台编译器 可是怎么试都不行 最后发现是 命令行 里依然是 X86 的问题
  • Java多线程面试题及答案

    这篇文章主要是对多线程的问题进行总结的 因此罗列了40个多线程的问题 这些多线程的问题 有些来源于各大网站 有些来源于自己的思考 可能有些问题网上有 可能有些问题对应的答案也有 也可能有些各位网友也都看过 但是本文写作的重心就是所有的问题都
  • 向量正交 与 函数正交

    目录 1 向量内积和外积 1 1 向量内积 点乘 1 2 向量外积 差乘 2 向量的正交 3 函数的正交 4 函数正交的意义 1 向量内积和外积 1 1 向量内积 点乘 假设 a a1 a2 an b b1 b2 bn 则a与b的内积为 a
  • Android开发之多Fragment切换优化(解决切换卡顿)

    我想刚刚接触安卓的同学或许会这么写 FragmentManager fragmentManager getSupportFragmentManager FragmentTransaction fragmentTransaction frag