问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Activity持有多个Fragment的跳转和回退实现方案

发布网友 发布时间:2023-07-24 05:52

我来回答

1个回答

热心网友 时间:2024-10-22 14:46

现在大多使用Fragment的场景有两种,一种是一个APP只有一个Activity+很多Fragment。另一种是APP中的每一个模块是一个Activity + 多个Fragment。最近需要用到Fragment来替代部分Activity。所以思考一下有什么方案。
实现的需求
Fragment 能像Activity那样有一个栈,然后跳转的时候会把Fragment加入到栈中,按返回键的时候能按顺序回退栈中的Fragment。
退回到第一个Fragment的时候再按返回键就finish Activity。
在跳转的时候和回退的时候能切换标题。
在任意的Fragment中都有返回第一个Fragment的方法。
设计是这样的,首先定义一个接口:
public interface IFragmentCallBack {
/**
* 从一个Fragment 跳到另一个Fragment
*
* @param tag
* @param current
*/
void jump(String tag, BaseFragment current);

/**
* 返回第一个Fragment
*/
void home();
}

定义一个BaseFragmentActivity实现这个接口,在onCreate方法中:
//处理异常退出恢复情况
if (savedInstanceState != null) {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null && fragments.size() > 0) {
boolean showFlag = false;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
for (int i = fragments.size() - 1; i >= 0; i--) {
Fragment fragment = fragments.get(i);
if (fragment != null) {
if (!showFlag) {
ft.show(fragments.get(i));
showFlag = true;
} else {
ft.hide(fragments.get(i));
}
}
}
ft.commit();
}
}

上面代码是处理Activity异常退出时恢复Fragment并且防止Fragment显示重叠的。
实现的接口的方法中,有home()和jump(),home的主要用能是跳回第一个Fragment,jump是用来通过tag跳转Fragment的,
home 实现如下:
@Override
public void home() {
while (getSupportFragmentManager().getBackStackEntryCount() != 1) {
getSupportFragmentManager().popBackStackImmediate();
}
}

jump 实现如下
@Override
public void jump(String tag, BaseFragment current) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
HashMap<String, FragmentMole> moles = getFragmentMole();
BaseFragment target = (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
if (target == null) {
target = moles.get(tag).getFragment();
transaction.hide(current)
.add(getContentId(), target, tag)
.addToBackStack(null)
.commit();
} else {
transaction.hide(current).show(target).commit();
}
setTitle(moles.get(tag).getTitle());
}

这里使用了add、show、hide方法,把Fragment添加到BackStack中,方便后面回退。上面使用了FragmentMole和 getFragmentMole、getContentId,getFragmentMole是抽象方法需要子类自己实现,getContentId也是抽象的,用于提供显示Framgent的布局id。
FragmentMole:
public class FragmentMole {
public BaseFragment fragment;
public String title;

public FragmentMole(BaseFragment fragment, String title) {
this.fragment = fragment;
this.title = title;
}

public BaseFragment getFragment() {
return fragment;
}

public String getTitle() {
return title;
}
}

需要添加回退功能。
/**
* 后退的时候按栈回退
*/
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() != 1) {
getSupportFragmentManager().popBackStackImmediate();
} else {
super.onBackPressed();
}
}

回退的时候使用popBackStackImmediate方法出栈,注意这里不能使用popBackStack 否则 getBackStackEntryCount可能返回不正确的值。
接下来需要设置页面默认的Fragment,也就是第一个Fragment ,在onCreate中调用:
FragmentMole defaultMole = getDefaultMole();
setTitle(defaultMole.getTitle());
getSupportFragmentManager().beginTransaction().add(getContentId(), defaultMole.getFragment(),
tag).addToBackStack(null).commit();

getDefaultMole 是一个抽象方法,用于返回默认的Fragment。
上面基本上就搭建完毕。
使用的时候,Activity继承BaseFragmentActivity ,然后实现getDefaultMoudle()、getContentId、getFragmentMole 方法
getContentId返回布局的ID,Fragment会在该布局中显示
getFragmentMole返回一个HashMap,key为fragment的tag,值为FragmentMole。
getDefaultMoudle直接new 一个FragmentMole即可。
最后,Fragment需要提供一个注入IFragmentCallback的构造方法。然后在Fragment中调用 callback.jump(tag,this)就可以跳转了,callback.home()可以回到第一个页面。
如果回退的时候需要改变标题需要重写Fragment的onHiddenChanged(boolean hidden)方法。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
快手极速版怎么绑定不了微信? 本班数学期中测试的优秀率是50%是什么意思 期中测试中全班56名同学有42人达到了优秀标准熊启中是稠剂的优秀率是... 期中测试中,全班56名同学,有49跟达到了优秀标准,求期中测试的优秀率是... 东瓜怎样吃,是减肥的最佳效果呢? 木耳冬瓜瘦肉汤怎么做味道极佳? 黑木耳冬瓜肉末汤美食做法 和前男友分手一年多了,也没联系过,怎么昨晚突然梦到他,而且感觉好真实... 面对分手两年多后的前男友,我应该怎么办 ...了微信但不说话,相亲女加了微信却不聊天,这是什么心态?_百... 如何从一个fragment中跳转到另一个fragment中 android fragment切换到另一个fragment点返回键返回上一个fragment 周口沈丘中考分数线2023 铂德gtr功率多少 女儿慌忙止住我说小声点儿你这一吵会把阳光下跑的运用了什么修辞手法... 宝贝严重违规被小儿删除,可以马上在重新发布吗 嬛嬛来了让三人隐藏起来怎么过 贵州省考警察职位属于A类还是 飞思卡尔单片机如何像51单片机那样下载程序(烧写hex文件)而不让别人看... 《甄嬛传》皇上有没有爱过甄嬛,有什么依据、 我是当民航飞行员,问题如下~ 月经不调越南语怎么写 老班长轻声对我说:“小声点儿,小梁!咱们俩是党员,你既然知道了,可不要... android中Fragment的切换方法。 南苑机场到圆明园怎么走 询小天鹅全自动洗衣机使用说明书,最好有线路图 不完美身材怎么选择婚纱掩饰缺陷 不完美身材选择婚纱掩饰缺陷的方法 ...fragment中有Listview,通过点击item跳转到另一个有ListView的fragment... 南方航空公司今年招的是民用机飞行员还是运输机飞行员?? 哈弗h52.0l5速能改6速吗 宁波浅水湾影视文化中心地址 2010年文综错10个选择题,大约能的多少分?大题判的严吗?我答得一般 女主叫许钱钱男主叫冷朔的小说 ...警察)要不要考公安基础知识,还有它属于A类还是B类 求小说无良神医 全集 作者:朴实的黄牛 凯恩斯主义的弊端是什么 单个开关键功放最佳设置参数是多少 猎兵级哪个子型号好 汇华资讯背调严格吗 病毒细菌感染发烧能喝抗病毒口服液吗 Android中Fragment跳转到另一个Fragment后返回的问题。 《下雨时蔷薇会开》读后感 ...fragment中的fragment跳转到另一个fragment(不是viewpager中的),怎... 坐月子鸡汤里可以放红枣和花生吗 反西格马负超子的发现是什么? 带有欢字和超子怎样组成网名 病毒性感冒发烧怎么办?需要用抗病毒口服液吗? 诺瓦星云有背调吗 《隐世录》小剧场:人气偶像大起底! 百度云管家上的图片被本地手机图片覆盖怎么找回