Android,activity+多个fragment页面切换逻辑

在Android app开发中,常用一个activity+多个fragment的UI结构,fragment之间有层级关系。fragment的显示与调度需要用到activity的fragmentManager,并且要封装一些方法共ui层调用。但是如果在activity里面直接写,会显得activity代码臃肿,那么需要封装一个辅助类

例如 AppPageHelper

java 复制代码
public class DemoPageHelper {
    private FragmentManager mFragmentManager;
    private boolean mIsAtXxxPage;

    private static final class DemoPageHelperInstanceHolder {
        private static final DemoPageHelper INSTANCE = new DemoPageHelper();
    }

    public static DemoPageHelper getInstance() {
        return DemoPageHelperInstanceHolder.INSTANCE;
    }

    private DemoPageHelper() {
        // 构造私有化
    }

    // 初始化这个辅助类,注入Activity的fragmentManager
    public void init(FragmentManager fragmentManager) {
        mFragmentManager = fragmentManager;
    }

    // 释放fragmentManager,避免页面销毁后内存泄露
    public void release() {
        mFragmentManager = null;
    }

    // 显示1级页面,加到activity容器中,但不加到fragment返回栈
    // 不加到返回栈中,fragmentManager的popBackStack不影响该页面;
    // 对于Activity的onBackPressed(),如果在返回栈中的页面调用,则效果同popBackStack;如果未入栈的1级页面在前台显示时调用,则页面和activity一起退出
    public void showLevel1(Fragment fragment, String tag) {
        if (mFragmentManager.getBackStackEntryCount() > 0) {
            // 清空返回栈,露出没入栈的rootFragment
            mFragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
        Fragment rootFragment = mFragmentManager.findFragmentByTag(tag);
        if (rootFragment == null) {
            mFragmentManager.beginTransaction().add(R.id.container, fragment, tag).commit();
        }
        //mFragmentManager.executePendingTransactions();
    }

    // 显示2、3...级页面,需要加到fragment返回栈
    public void showLevel2(Fragment newFragment, String tag) {
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        Fragment topFragment = getStackTopFragment();
        transaction.hide(topFragment).add(R.id.container, newFragment, tag).addToBackStack(tag).commit();
        //mFragmentManager.executePendingTransactions();
    }

    private Fragment getStackTopFragment() {
        int backStackPageCount = mFragmentManager.getBackStackEntryCount();
        String fragmentTag;
        if (backStackPageCount == 0) {
            fragmentTag = RootFragment.class.getSimpleName();
        } else {
            fragmentTag = mFragmentManager.getBackStackEntryAt(backStackPageCount - 1).getName();
        }
        return mFragmentManager.findFragmentByTag(fragmentTag);
    }

    public void back() {
        // 作用于返回栈,弹出栈顶,显示栈内上一级页面;如果当前是栈内第一个页面则清空返回栈;如果已清空栈,则无效果。
        mFragmentManager.popBackStack();
    }

    // Xxx页面是否正在前台显示
    public boolean isAtXxxPage() {
        return mIsAtXxxPage;
    }

    public void setAtXxxPage(boolean atXxxPage) {
        mIsAtXxxPage = atXxxPage;
    }
}

Activity中使用

java 复制代码
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        DemoPageHelper.getInstance().init(getSupportFragmentManager());
        DemoPageHelper.getInstance().showLevel1(new RootFragment(), RootFragment.class.getSimpleName());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        DemoPageHelper.getInstance().release();
    }

fragment中使用

java 复制代码
    @Override
    public void onStart() {
        super.onStart();
        DemoPageHelper.getInstance().setAtXxxPage(true);
    }

    @Override
    public void onStop() {
        super.onStop();
        DemoPageHelper.getInstance().setAtXxxPage(false);
    }

    // 在非1级页面,返回到上一级
    DemoPageHelper.getInstance().back();

    // 显示非一级页面
    DemoPageHelper.getInstance().showLevel2(new TwoFragment(), TwoFragment.class.getSimpleName());

    // 在1级页面退出app,直接finish activity
相关推荐
Highcharts.js1 小时前
教程:基于 React + Highcharts 构建一个单页应用程序、按需数据拉取与图表渲染
开发语言·前端·数据结构·react.js·前端框架·highcharts·页面应用
头发还在的女程序员2 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats3 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
xingxiliang3 小时前
深入浅出 Android CTS 视频测试:从环境搭建、用例设计到底层通信原理
android·音视频
我命由我123453 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
爱写代码的小朋友5 小时前
从零开始学 Win32 API:C++ 窗口编程实战(VS Code + MinGW-w64 命令行详解)
开发语言·c++
果汁华5 小时前
Function Calling 与 Python 实战完整指南
开发语言·网络·python
小小晓.5 小时前
C++:语句和作用域
开发语言·c++
雨白5 小时前
深入理解 Kotlin 协程 (八):拾遗补阙,探秘官方框架的调度细节与取消闭环
android·kotlin
都叫我大帅哥6 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程