最近出于个人兴趣,在山寨知乎日报app。
发现在知乎日报app中,首页为一个基Fragment,直接在首页按back键,会退出程序。而在通过左边的导航栏选取兴趣主题页面后,例如 日常心理学 页面,会有一个将首页Fragment加入 后退栈的感觉。所以在兴趣Fragment页面按back返回时会先退到首页。
做法:
一开始我就是用 FragmentTransaction 的addToBackStack()方法,将首页加入BackStack,后来发现 这种方法在切换回来时,不好修改上面的Toolbar区域的title(我没找到,如果您知道希望能告诉我)。卡在这一段时间后,
我想到了另一个方法:
初始化时,首页Fragment是Add加入的,后续切换Fragment使用replace替换,那如何实现这种在别的主题页面back时返回主页呢?
我在Activity里监听Back按键,如果当前Fragment是主题类Fragment,则replace替换成主页Fragment,并且同步修改Toolbar区域的内容。
先上效果图:知乎日报原版如下:
DEMO效果如下:
===========================优雅的分割线=============================
核心代码如下:
Activity初始化时,设置默认Fragment(首页):
private void setDefaultFragment() { //设置AppBar mTitle = "首页"; mToolbar.setTitle(mTitle); //Fragment的初始化 mFm = getSupportFragmentManager(); FragmentTransaction ft = mFm.beginTransaction(); mCurrentFragment = mFm.findFragmentById(R.id.content_container); //如果为空 说明是初始化, 不为空说明可能是屏幕旋转等事件 if (mCurrentFragment == null) { TipsUtils.LogI(TAG, " mCurrentFragment == null "); //mCurrentFragment = new FragmentMain(); mCurrentFragment = MainFragment.newInstance(mTitle); ft.add(R.id.content_container, mCurrentFragment); } //LeftMenu区域: mLeftFragment = (LeftFragment) mFm.findFragmentById(R.id.fl_leftmenu); if (mLeftFragment == null) { mLeftFragment = new LeftFragment(); ft.add(R.id.fl_leftmenu, mLeftFragment); } ft.commit(); }
对代码简单说明一下:AppBar区域本DEMO使用Toolbar,Fragment初始化即首页初始化,LeftMenu区域是左侧拖拽导航栏代码(与本文无关),
===========================优雅的分割线=============================
点击某个兴趣主题后,切换Fragment代码如下:
mLeftFragment.setOnItemClickListener(new LeftFragment.OnItemClickListener() { @Override public void onItemClick(int id, String name) { FragmentTransaction ft = mFm.beginTransaction(); //这里每次都new一个新的,参考知乎也是如此做 ThemeContentFragment mThemeFragment = new ThemeContentFragment(); //将该主题对应的URL传入: Bundle bundle = new Bundle(); //传入接收到的主题的Url bundle.putInt(ThemeContentFragment.KEY_URL_ID, id); mThemeFragment.setArguments(bundle); ft.replace(R.id.content_container, mThemeFragment, TAG_THEME); ft.commit(); //手动关闭左侧菜单 mDrawerLayout.closeDrawer(Gravity.LEFT); //设置AppBar标题: mToolbar.setTitle(name); } });对代码简单说明一下:这里使用replace 方法替换Fragment,并且给主题Fragment页面加入一个TAG,方便在BackPressed()方法里获取。
===========================优雅的分割线=============================
在Activity里 监听back的按下:
@Override public void onBackPressed() { //菜单打开的情况下 按 back ,则直接关闭菜单 if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) { mDrawerLayout.closeDrawer(Gravity.LEFT); //return true; } else { //先通过TAG获取Fragment //如果不为空 说明当前有 主题Fragment ,则模拟Fragment进backstack:将主页的Fragment显示出来 if (null != mFm.findFragmentByTag(TAG_THEME)) { TipsUtils.LogI(TAG, "null != mThemeFragment"); FragmentTransaction ft = mFm.beginTransaction(); ft.replace(R.id.content_container, mCurrentFragment); ft.commit(); //设置AppBar Title mToolbar.setTitle(mTitle); } else { super.onBackPressed(); } } }对代码简单说明一下:标红区域为本文相关代码,先通过TAG获取Fragment,如果不为空,说明当前Fragment是主题页面,应该模拟back返回主页的效果,所以使用replace方法替换Fragment为首页的Fragment,并修改Toolbar内容。 如果为空,则说明正处在首页,则直接返回,不干预操作。
===========================优雅的分割线=============================
最后,好了,不说了,我要去过节了,各位情人节愉快。