Fragment回退栈相关操作

在我的场景里,会创建多个Fragment,Fragment之间可以互相跳转,点击返回键需要一级一级往上返回。因此需要一个类似于Activity的回退栈,当然没必要做到Activity那么复杂,满足先进先出的效果即可。

添加Fragment回退栈

添加个Fragment,并将其加入回退栈,代码如下:

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
        .add(R.id.frag_container, fragment)
        .addToBackStack(null)
        .commitAllowingStateLoss();

方法addToBackStack表示将Fragment加入到回退栈中。
在返回时,Fragment出栈的逻辑如下:

FragmentManager fragmentManager = getSupportFragmentManager();
int backStackCount = fragmentManager.getBackStackEntryCount();
if (backStackCount > 0) {
    fragmentManager.popBackStack();
}

方法popBackStack将一个Fragment出栈,调用前可以先通过getBackStackEntryCount方法判断当前回退栈是否还有Fragment。

获取顶部的Fragment

我的场景中,经常要获取栈顶的Fragment进行操作,然而没有找到直接获取栈顶Fragment的方法。在最初的实现中,借用了Stack来实现我的逻辑。

private final Stack<Fragment> mFragmentStack = new Stack<>();

public void addFragment(Fragment fragment) {
    FragmentManager fragmentManager = getSupportFragmentManager();
	fragmentManager.beginTransaction()
        .add(R.id.frag_container, fragment)
        .addToBackStack(null)
        .commitAllowingStateLoss();
	mFragmentStack.push(fragment);
}

public void popFragment() {
    FragmentManager fragmentManager = getSupportFragmentManager();
	int backStackCount = fragmentManager.getBackStackEntryCount();
	if (backStackCount > 0) {
    	    fragmentManager.popBackStack();
            mFragmentStack.pop();
	}
}

public Fragment getTopFragment() {
    return mFragmentStack.peek();
}

然而使用Stack后发现线上版本会发生crash。mFragmentStack里的Fragment和FragmentManager中的Fragment可能不一致。主要原因是Activity状态恢复导致的,Stack数据没有saveInstanceState,Activity恢复时执行mFragmentStack.peek会导致EmptyStackException
要修复这个问题,可以将Stack数据也进行状态保存。但我仔细想过后觉得,Stack和FragmentManager的作用是一致的,加一个Stack本身是不合理的,后续代码变更,也很难保证Stack和FragmentManager回退栈数据是一致的。为此我开始想另外的解决方案。
回到我最开始的需求,我就是想获取顶部的Fragment,能不能用FragmentManager提供的接口来实现呢?阅读相关源码后,有个方法引起了我的注意:

/**
 * Return the BackStackEntry at index <var>index</var> in the back stack;
 * entries start index 0 being the bottom of the stack.
 */
@NonNull
public BackStackEntry getBackStackEntryAt(int index) {
    return mBackStack.get(index);
}

获取到的BackStackEntry有id和name属性,为此我想到一个办法:

public Fragment getTopFragment() {
    int count = getSupportFragmentManager().getBackStackEntryCount();
    FragmentManager.BackStackEntry entry = getSupportFragmentManager().getBackStackEntryAt(count - 1);
    return getSupportFragmentManager().findFragmentByTag(entry.getName());
}

该代码中,首先获取回退栈数量,然后通过getBackStackEntryAt方法,获取最后一个回退栈数据。最后通过findFragmentByTag找到顶部的Fragment。不过这里要注意的是,在添加回退栈时,需要设置tag。具体代码如下:

public void addFragment(Fragment fragment) {
    String tag = getFragmentTag();
    FragmentManager fragmentManager = getSupportFragmentManager();
	fragmentManager.beginTransaction()
        .add(R.id.frag_container, fragment, tag)
        .addToBackStack(tag)
        .commitAllowingStateLoss();
}

上面代码中,add和addToBackStack方法都指定了同一个tag,保证后续能够通过findFragmentByTag找到相应的Fragment。
方案最终验证OK。

原文链接:https://www.cnblogs.com/carvergit/p/17121921.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Fragment回退栈相关操作 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • Android页面渲染效率优化实践

      1.车系页布局渲染现状  车系页是重要的车系信息页面,更新迭代多年,页面布局不断变化,xml布局文件越写越复杂。 获取车系页布局文件耗时:         startTime = System.currentTimeMillis();         setContentView(R.layout.car_series_revision_activity…

    Android 2023年4月17日
    00
  • Android中drawable和mipmap到底有什么区别

    欢迎通过我的个人博客来查看此文章 老项目代码中发现有的图片放到了drawable中, 有的图片放到了mipmap中, 开发时秉承哪个目录下文件多放哪里的原则, 偶尔有疑惑搜一搜文章, 看到了结论也就这么使用了, 不过今日有时间, 依次检验了一下文章中的内容, 发现和实际的表现出入甚远. 常见的几种结论 Case 1 drawable会剔除其它密度, mipm…

    Android 2023年4月18日
    00
  • Android 启动优化(二) – 有向无环图的原理以及解题思路

    Android 启动优化(一) – 有向无环图 Android 启动优化(二) – 拓扑排序的原理以及解题思路 Android 启动优化(三) – AnchorTask 使用说明 Android 启动优化(四)- 手把手教你实现 AnchorTask Android 启动优化(五)- AnchorTask 1.0.0 版本更新了 Android 启动优化(六…

    Android 2023年4月18日
    00
  • 安卓常用shell命令大全

    前言 这篇笔记用来收集在日常开发中所用到的安卓adb shell命令,参照了一些大佬的再加上我自己平时用到的整理在了一块儿,感谢无私共享的大佬们。 将会持续更新,欢迎收藏~ 一、基本用法 命令语法 adb 命令的基本语法如下: adb [-d|-e|-s <serialNumber>] <command> 如果只有一个设备/模拟器连接…

    Android 2023年4月18日
    00
  • 【FAQ】获取Push Token失败,如何进行排查?

    一、 获取Push Token的方式 获取Push Token有两种方式:一种是调用getToken方法向Push服务端请求Token,当getToken方法返回为空时,Token可通过onNewToken方法返回,因此需要实现onNewToken方法;另一种是自动初始化,Token通过onNewToken方法返回。这两种方法的详细说明可看获取和注销Toke…

    Android 2023年4月18日
    00
  • 免费广告效果监测服务,实现全链路营销效果跟踪

    广告主们都希望以低预算获得更高的广告投放收益,在投放广告后,想要了解高回报的渠道,往往需要收集并分析繁杂的数据,耗时耗力。通过广告监测,广告主可以准确的追溯用户渠道来源,看到不同流量的用户价值,分析广告投放效果,从而指导广告的出价和投放素材的优化,把预算花在刀刃上。 针对广告主们广告监测的需求,华为分析服务提供免费的广告监测能力,为有广告监测需求的广告主节省…

    Android 2023年4月17日
    00
  • 华为运动健康服务Health Kit 6.10.0版本新增功能速览!

    华为运动健康服务(HUAWEI Health Kit)6.10.0 版本新增的能力有哪些? 阅读本文寻找答案,一起加入运动健康服务生态大家庭! 一、 支持三方应用查询用户测量的连续血糖数据 符合申请Health Kit服务中开发者申请资质要求的企业开发者,可申请访问用户的心率、压力、血糖等健康数据。 在新版本中,血糖数据类型在原有指尖血糖数据开放的基础上,新…

    Android 2023年4月17日
    00
  • Android Studio的安装及环境配置

    Android Studio的安装及环境配置 安装jdk 下载及安装Android Studio 下载官网:https://developer.android.google.cn/studio/ 往下滑: 建议下载到除C盘以外的盘: 下载好安装程序之后 双击安装:一路next,install Android Virtual Device安卓虚拟设备,就是在电…

    Android 2023年4月24日
    00
合作推广
合作推广
分享本页
返回顶部