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
相关推荐
普通人620 分钟前
php+html+canvas实现树状打开的结构
开发语言·javascript·html5·1024程序员节
wuminyu36 分钟前
JMM学习总结:深入理解happens-before关系
java·linux·c语言·jvm·c++
电商API_1800790524737 分钟前
反向海淘多币种结算:汇率该在哪个时点被冻结
java·开发语言·数据库·跨境电商·1688 api
三少爷的鞋1 小时前
Android 协程实践:为什么不应将 `supervisorScope` 作为常规方案
android
开开心心就好1 小时前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
Want5951 小时前
Python炫酷烟花①
开发语言·python
Pniubi2 小时前
模拟一个充值送token怎么保证幂等?一致性?原子性?
java
企业数字化笔记2 小时前
多租户配额怎么控制?用量口径、并发预留与超额处理的实现方法
java·数据库·spring boot
承渊政道2 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(从ChatGLM本地化到LoRA、PEFT的高级微调)
android·人工智能·pytorch·chatglm·本地化部署·大模型开发与微调
星夜离尘562 小时前
MATLAB 线性去趋势为何损伤低频正弦:联合最小二乘估计幅相与漂移
开发语言·matlab