CorePage(Android使用Fragment打造万能页面切换框架)

本文介绍了一种使用Fragment实现的灵活页面切换框架。通过BaseActivity作为容器管理Fragment的跳转和回退,利用栈结构记录已打开的页面,支持页面间的回调交互。文章详细解释了openPage和gotoPage方法的工作原理及不同场景下的onFragmentResult实现。

来源Android使用Fragment打造万能页面切换框架

关键思路:

1、BaseActivity作为fragment的容器,里面负责跳转入口openPage和gotoPage
openPage: 打开一个新的fragment,默认都addToBackStack
gotoPage: 跳转的之前打开过的fragment。在BaseActivity有一个栈,保存所有已打开过的activity,gotoPage就是遍历所有的activity,然后findFragmentByTag找到fragment,如果 没找到,就finish activity,继续下一个activity

2、每个Activity中的Fragment没有另外用一个集合管理,都交给了该activity

3、同一activity中的不同fragment间onFragmentResult实现:采用回调方式

//调用方式
	openPageForResult("test2",bundle,CoreAnim.fade,requestCode);
	
	//获取想要打开的Fragment实例
	BaseFragment frg = (BaseFragment)         CorePageManager.getInstance().openPageWithNewFragmentManager(getSupportFragmentManager(), pageName, bundle, animations, addToBackStack);
                if (frg == null) {
                    return null;
                }
	final BaseFragment opener = fragment;
	//设置requestCode和回调listener给想要打开的fragment,便于关闭时调用回调函数
	frg.setRequestCode(page.getRequestCode());
	frg.setFragmentFinishListener(new BaseFragment.OnFragmentFinishListener() {
		@Override
		public void onFragmentResult(int requestCode, int resultCode, Intent intent) {
			//收到回调,调用原fragment的onFragmentResult方法
			opener.onFragmentResult(requestCode, resultCode, intent);
		}
	});
	
	
	//被打开界面中调用回调函数,
	Intent intent=new Intent();
	Bundle bundle=new Bundle();
	bundle.putString("data","this is a result");
	intent.putExtras(bundle);
	setFragmentResult(500,intent);
	popToBack();
	
	//setFragmentResult中调用之前的回调,我觉得这里可以像Activity那样先设置resultIntent,
	//在popToBack方法中再调用回调mFragmentFinishListener
	public void setFragmentResult(int resultCode, Intent intent) {
        if (mFragmentFinishListener != null) {
            mFragmentFinishListener.onFragmentResult(mRequestCode, resultCode, intent);
        }
    }

4、不同activity中onFragmentResult实现:采用回调方式,不过是借助activity的setResult和onActivityResult

	//新activity中
	fragment = (BaseFragment) CorePageManager.getInstance().openPageWithNewFragmentManager(getSupportFragmentManager(), pageName, bundle, null, addToBackStack);
	if (fragment != null) {
		if ("true".equalsIgnoreCase(startActivityForResult)) {
			fragment.setRequestCode(page.getRequestCode());
			fragment.setFragmentFinishListener(new BaseFragment.OnFragmentFinishListener() {
				@Override
				public void onFragmentResult(int requestCode, int resultCode, Intent intent) {
					BaseActivity.this.setResult(resultCode, intent);
				}
			});
		}
	}
	
	//原来的activity中
	@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult from baseActivity" + requestCode + " " + resultCode);
        if (mFragmentRequestCode == requestCode && mFragmentForResult != null) {
            mFragmentForResult.onFragmentResult(mFragmentRequestCode, resultCode, data);

        }
        super.onActivityResult(requestCode, resultCode, data);
    }

5、注意下BaseActivity中的onBackPressed,如果fragment个数大于1,交给系统自动弹栈,否则 关闭当前activity

6、注意下BaseActivity中的onKeyDown,栈顶的fragment能处理,就交给fragemnt处理,否则 交给activity处理

7、关闭Activity的动画是用该activity中第一个fragment的动画。

缺点

不支持Activity的launchMode 4中方式,可以参考FragmentStack项目,如果是singleInstance模式,newActivity设置为true,并给新建的Activity添加flag。其他launchMode都在同一个activity中。

FragmentStack项目

1、fragment栈没有交给activity管理,由FragmentStack统一管理 private ArrayList<ArrayList<RootFragment>> stackList = new ArrayList<>(); 只有singleInstance mode的时候stackList才会新建一个ArrayList,代表一个新的栈。

2、onBackPressed中,只取stackList最上层ArrayList中的最后两个fragment隐藏和显示。

缺点:
1、没有实现自动路由
2、没有实现onFragmentResult
3、由于没有用Activity的栈来管理fragment,所以切换动画只能手动设置fragment root view动画。

转载于:https://my.oschina.net/bruces/blog/802309

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值