【Android】多Fragment切换以及在主Activity中判断返回按键

一、Fragment的切换

Fragment网上有很多种切换方式,比较常见的就是使用同名或者数字标签索引Fragment,我这里也记录一下我的索引方法。


我的切换Fragment思路如下:

1、Fragment的管理使用Map<String , Fragment>  管理,String 为Fragment的同名实例化标签,Fragment则是具体的Fragment的实例化对象

2、先判断是否是需要实例化的Fragment(Y:实例化后继续向下          N:跳过向下)

3、再判断是否可以跳转到相应的Fragment (Y:判断是否需要Add  N:show需要的,hide不需要的)


管理Fragment的使用Map如下:

private Map<String, Fragment> mFragments = new HashMap<>();

假设此处管理三个Fragment,分别是 SpeFragment,HeoFragment,PleFragment:

private SpeFragment speFragment;
private HeoFragment heoFragment;
private PleFragment pleFragment;

写实例化Fragment的函数(如果以后新增Fragment则在此处添对应的实例化方法):

private void iniFragment(String name){
        switch (name){
            case "speFragment":
                speFragment = new SpeFragment();
                if (!mFragments.containsKey(name)){
                    mFragments.put(name,speFragment);
                }
                break;
            case "heoFragment":
                heoFragment = new HeoFragment();
                if (!mFragments.containsKey(name)){
                    mFragments.put(name,heoFragment);
                }
                break;
            case "pleFragment":
                pleFragment = new PleFragment();
            if (!mFragments.containsKey(name)){
                mFragments.put(name,pleFragment);
            }
            break;
        }
    }


写切换Fragment的函数,这里主要是做hide和show操作:

/**
     * 显示Fragment,隐藏不需要使用的Fragment
     * @param fragmentName 需要显示的Fragment
     */
    public void switchFragment(String fragmentName){
        mFragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        if (!mFragments.containsKey(fragmentName)){
            Log.i(TAG, "switchFragment: 添加Frag");
            iniFragment(fragmentName);
        }

        if (!mFragments.containsKey(fragmentName)){
            Log.i(TAG, "switchFragment: 不存在此类 Fragment,请检查是否在iniFragment中注册过");
            return;
        }

        if (mFragments.containsKey(fragmentName)){
            Log.i(TAG, "switchFragment: 包含Frag");

            for (Map.Entry<String,Fragment> entry:mFragments.entrySet()){
                if (!mFragments.get(fragmentName).isAdded() && entry.getKey().equals(fragmentName)){
                    ft.add(R.id.index_fl,mFragments.get(fragmentName));
                }else {
                    if (entry.getKey().equals(fragmentName)){
                        ft.show(entry.getValue());
                    }else {
                        ft.hide(entry.getValue());
                    }
                }
            }
            ft.commit();
        }

    }


如果不想用hide和show,就想用replace怎么办?构造一个同名函数,参数变一下即可:

/**
     * Replace替换Fragment
     * @param fragmentName 需要替换的名字
     * @param isReplaced    true为确认替换
     */
    public void switchFragment(String fragmentName, boolean isReplaced){
        mFragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        if (!mFragments.containsKey(fragmentName)){
            iniFragment(fragmentName);
        }

        if (!mFragments.containsKey(fragmentName)){
            Log.i(TAG, "switchFragment: 不存在此类 Fragment,请检查是否在iniFragment中注册过");
            return;
        }

        if (mFragments.containsKey(fragmentName)){
            if (isReplaced){
                ft.replace(R.id.index_fl,mFragments.get(fragmentName));
                ft.commit();
            }
        }
    }


对应的使用方法为,例如切换到pleFragment:
switchFragment("pleFragment")


如何在不同的Fragment中切换呢?当然是将Map变成一个相对于这些管理Fragment的全局变量了,我的做法是将含有Fragment集合Map 静态(static)实例化的到的主Activity中,让Fragmet可以直接调用主Activity中的管理Fragment的Map,这样的Map的生命周期也是随着Activity的结束而结束。

还有一个很好的做法,就是单独封装一个类进行管理即可。


总之,集思广益好了,做法有优劣,当然都是相对的。



二、如何在含有很多Fragment中,准确的判断返回按键的所属范围?

首先先明确一下,我这里的实现返回监听只放到了主Activity中,Fragment不用监听;


很多人可能会用如下代码去寻找:

Fragment mCurrentFragment = mFragmentManager.findFragmentById(R.id.index_fl);
但似乎在使用过程中发现,如果只是hide了Fragment,那么之后使用findFragmentById得到的Fragment也会不变

...

不说了直接放代码:

public void onBackPressed() {
        //Fragment mCurrentFragment = mFragmentManager.findFragmentById(R.id.index_fl);
        String mCurrentFragmentName = "unknow";
        List<Fragment> fms = mFragmentManager.getFragments();
        for (Fragment m : fms){
            if (!m.isHidden() && m.isAdded()){
                Log.i(TAG, "onBackPressed: 当前显示的是"+ m.getClass().getSimpleName());
                mCurrentFragmentName = m.getClass().getSimpleName();
            }
        }

        switch (mCurrentFragmentName){
            case "pleFragment":
                exitApp();
                break;
            case "speFragment":
                Log.i(TAG, "onBackPressed: " + mFragmentManager.getFragments().size());
                switchFragment("pleFragment");
                break;
            default:
                break;

        }
    }
如上代码所表述,将所有的Fragment从FM中作为一个List拿到,遍历一下当前哪个隐藏了哪个显示的,然后就确认了当前正show的Fragment,这样讲捕获的返回键就可以配合下面的switch来对应不同的功能了。


如果replace了怎么办,加判定条件哟,Fragment有很多判定方法,根据程序设计来纠正自己的实现逻辑,才可以慢慢走出一套自己的风格代码,当然,看看别人的车轮,也是一种体验,尤其是造的很好的车轮。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值