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

来源:互联网 发布:windows系统制作mac 编辑:程序博客网 时间:2024/05/20 20:18

一、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 0
原创粉丝点击