*
* @return PageManager
*/
public static CorePageManager getInstance() {
if (mInstance == null) {
synchronized (CorePageManager.class) {
if (mInstance == null) {
mInstance = new CorePageManager();
}
}
}
return mInstance;
}
/**
* 初始化配置
*
* @param context 上下文
*/
public void init(Context context) {
try {
mContext = context.getApplicationContext();
readConfig();
} catch (Exception e) {
e.printStackTrace();
}
}
}
其中init函数暴露给程序入口,进行配置文件的读取。一般放在Application的子类的onCreate方法中即可。
到这里为止,基本上我们一切已经就绪了。就差如何切换了。这里,在CorePageManager类中再提供两个核心函数,用于处理页面切换。
下面这个函数是页面切换的核心函数,首先根据参数从map中拿到对应的实体类,假设存在这个页面,通过class名用反射获得该Fragment对象,调用前面写好的创建Bundle的函数得到页面参数,并与当
前函数中的入参bundle进行合并。将参数设置给fragment对象,开启一个fragment事务,查找id为fragment_container的fragment容器,如果该容器已经有fragment,则隐藏它,如果该函数传递了动画参
数,则添加页面切换动画,然后将反射获得的fragment对象添加到该容器中,如果需要添加到返回栈,则调用addToBackStack,最后提交事务并返回该fragment对象。
整个函数很简单,就是我们平常在activity中写的切换fragment的代码
/**
* 页面跳转核心函数之一
* 打开一个fragemnt
*
* @param fragmentManager FragmentManager管理类
* @param pageName 页面名
* @param bundle 参数
* @param animations 动画类型
* @param addToBackStack 是否添加到返回栈
* @return
*/
public Fragment openPageWithNewFragmentManager(FragmentManager fragmentManager, String pageName, Bundle bundle, int[] animations, boolean addToBackStack) {
BaseFragment fragment = null;
try {
CorePage corePage = this.mPageMap.get(pageName);
if (corePage == null) {
Log.d(TAG, "Page:" + pageName + " is null");
return null;
}
fragment = (BaseFragment) Class.forName(corePage.getClazz()).newInstance();
Bundle pageBundle = buildBundle(corePage);
if (bundle != null) {
pageBundle.putAll(bundle);
}
fragment.setArguments(pageBundle);
fragment.setPageName(pageName);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (animations != null && animations.length >= 4) {
fragmentTransaction.setCustomAnimations(animations[0], animations[1], animations[2], animations[3]);
}
Fragment fragmentContainer = fragmentManager.findFragmentById(R.id.fragment_container);
if (fragmentContainer != null) {
fragmentTransaction.hide(fragmentContainer);
}
fragmentTransaction.add(R.id.fragment_container, fragment, pageName);
if (addToBackStack) {
fragmentTransaction.addToBackStack(pageName);
}
fragmentTransaction.commitAllowingStateLoss();
//fragmentTransaction.commit();
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "Fragment.error:" + e.getMessage());
return null;
}
return fragment;
}
而上面这个函数中的id值在一个基础的布局中,之后的Fragment都会添加到该布局中去。我们的基类Activity也将使用这个布局,这个后续编写BaseActivity的时候会提到
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
此外,我们再提供一个核心函数。就是如果返回栈中存在了目标fragment,则将其弹出,否则新建fragment打开。
/**
* 页面跳转核心函数之一
* 打开一个Fragement,如果返回栈中有则出栈,否则新建
*
* @param fragmentManager FragmentManager管理类
* @param pageName 页面别名
* @param bundle 参数
* @param animations 动画
* @return 成功跳转到的fragment
*/
public Fragment gotoPage(FragmentManager fragmentManager, String pageName, Bundle bundle, int[] animations) {
Log.d(TAG, "gotoPage:" + pageName);
Fragment fragment = null;
if (fragmentManager != null) {
fragment = fragmentManager.findFragmentByTag(pageName);
}
if (fragment != null) {
fragmentManager.popBackStackImmediate(pageName, 0);
} else {
fragment = this.openPageWithNewFragmentManager(fragmentManager, pageName, bundle, animations, true);
}