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
相关推荐
yaoxin5211231 小时前
434. Java 日期时间 API - Period 基于日期的时间段
java·开发语言·python
凡人叶枫2 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
学逆向的2 小时前
C++纯虚函数
开发语言·c++·网络安全
何极光2 小时前
IDEA集成Maven
java·maven·intellij-idea
程序员二叉2 小时前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉3 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
老马识途2.03 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
青山木3 小时前
Hot 100 --- 轮转数组
java·数据结构·算法
凡人叶枫3 小时前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
Qt程序员3 小时前
掌握 Linux 内核调度:从原理到实现(进程篇)
java·开发语言