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日

相关文章

  • 安卓常用shell命令大全

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

    Android 2023年4月18日
    00
  • Android Studio中的一些常见控件

    Android Studio是一款非常流行的用于开发Android应用程序的集成开发环境(IDE)。它提供了许多内置控件,使开发人员可以轻松创建应用程序界面和功能。在本文中,我们将介绍Android Studio中的一些常见控件,例如TextView,Button,EditText,ImageView等。 TextView控件 TextView是一个用于显示…

    Android 2023年4月17日
    00
  • Android报”StaleDataException”如何解决?

    StaleDataException 是一个非常常见的 Android 异常,它在我们开发中经常会遇到。它的含义是:数据已经过期了。在使用 Cursor 的时候,有可能会遇到这个异常,主要原因是由于在 Cursor 有效时执行了更新/删除操作,导致 Cursor 中的数据已经过期,无法进行操作。下面我将详细讲解这个异常的原因和解决办法。 原因 当我们使用 C…

    Android 2023年4月3日
    00
  • Android报”SecurityException”如何解决?

    首先我们需要知道在Android中,每个应用程序都会运行在自己的Sandbox中,这是为了保证应用程序之间的安全性和隔离性。这意味着当我们试图从应用程序中访问另一个应用程序或系统的一些敏感资源时,我们可能会遇到”SecurityException”异常。 该异常表示当前的应用程序没有足够的权限来执行某个操作。通常可以通过以下两种方式来解决该问题: 申请相关权…

    Android 2023年4月3日
    00
  • Android报”ANR(ApplicationNotResponding)error”如何解决?

    ANR是指Android应用程序无响应错误(Application Not Responding),它是指当应用程序执行了一个长时间操作而没有响应用户时产生的错误。在这种情况下,系统会向用户显示一个可关闭的对话框来告知用户该应用已停止响应,如果用户在几秒钟内不关闭该对话框,则系统会将该应用关闭。ANR异常一般产生的原因有以下几种: 主线程卡顿 : 执行耗时任…

    Android 2023年4月3日
    00
  • 鲸鸿动能广告接入如何高效变现流量?

    广告是App开发者最常用的流量变现方法之一,当App拥有一定数量用户时,开发者就需要考虑如何进行流量变现,帮助App实现商业可持续增长。 鲸鸿动能流量变现服务是广告服务依托华为终端强大的平台与数据能力为开发者提供的App流量变现服务,开发者通过该服务可以在自己的App中获取并向用户展示精美的、高价值的广告内容,并从中获得广告收益。开发者集成鲸鸿动能服务进行广…

    Android 2023年5月11日
    00
  • Android 监听短信数据库过滤获取短信内容上传至服务器

    前言 Android 监听短信的方式有两种 1、监听短信数据库,数据库发生改变时回调。 2、监听短信广播 其中第二种方式由于国内各厂家的定制Android 可能导致无响应 目前测试 魅族 无法监听到短信广播 本文介绍第一种方式监听短信 一、创建Service前台服务 package com.iwhalecloud.demo.SMS; import andro…

    Android 2023年4月18日
    00
  • 集成Health Kit时因证书问题出现错误码50063的解决方案

    一、问题描述及操作 应用集成Health Kit SDK后,在华为手机上进行登录授权时,返回错误码50063。 1、查看相关错误码。‘50063’在Health Kit错误码中的描述是“安装的HMS Core APK版本不匹配,无法调用接口。”提供的解决方案是“请安装最新版本的HMS Core(APK)后,再调用接口”。 2、根据文档中提供的解决方案,卸载了…

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