FragmentNav可以让你以类似启动Activity的操作启动/结束一个/多个Fragment。将你从冗长的AndroidManifest配置中解放出来,基于Task栈管理的设计可以让你的业务开发更加的高效便捷。
主要功能
1、支持以Task栈的形式批量管理Fragment
2、支持startFragmentForResult
3、支持BringToFront操作
4、Activity.onSaveInstanceState安全
使用
1、在同一个Task中启动Fragment
//创建一个带有一个String类型数据和特定页面动画的FragmentIntent
FragmentIntent fragmentIntent = new FragmentIntent(Fm01.class)
.putExtra(KEY_STRING, "StringExtra")
//可以通过FragmentIntent.getDefault()来配置默认页面动画
.setAnim(R.anim.page_start, R.anim.page_finish, R.anim.page_show, R.anim.page_hide);
//启动该Fragment
startFragment(fragmentIntent);
运行图:
2、在一个新的Task中批量启动Fragment
此方式可以方便的以业务栈的形式组织和管理Fragment,比如可以将多个获取用户输入的页面在一个Task中启动,在用户输入完毕并提交数据后一次性结束整个业务栈。
//添加FragmentIntent.FLAG_NEW_TASK以在一个新的task中启动FragmentIntent intent11 = new FragmentIntent(Fm11.class).addFlag(FragmentIntent.FLAG_NEW_TASK);
FragmentIntent intent12 = new FragmentIntent(Fm12.class);
FragmentIntent intent21 = new FragmentIntent(Fm21.class).addFlag(FragmentIntent.FLAG_NEW_TASK);
startFragment(intent11, intent12, intent21);
运行图:
3、结束Task
//结束当前Fragment所在的task,也可以调用FragmentNav.finishTask(Fragment)来结束指定Fragment的task,
//或调用FragmentNav.finishTasks(int... taskIds)来同时结束多个Task
finishTask();
运行图:
4、BringToFront
该操作类似Activity的BRING_TO_FRONT操作,效果为将一个已启动的非当前Fragment“带到”当前显示。
//将某个已启动的Fragment置顶显示
startFragment(new FragmentIntent(Fm01.class).addFlag(FragmentIntent.FLAG_BRING_TO_FRONT))
运行图:
5、startFragmentForResult
类似Activity中的startActivityForResult操作,在Fragment中调用setResult()后再回到调用页面可以将结果通过onFragmentResult(int requestCode, int resultCode, Object data);回调传递给调用页面。
//启动Fm01
startFragmentForResult(REQUEST_CODE, new FragmentIntent(Fm01.class));
@Override
public void onFragmentResult(int requestCode, int resultCode, Object data) {
super.onFragmentResult(requestCode, resultCode, data);
Androids.shortToast(getContext(), "onFragmentResult:\nRequestCode=>%s\nResultCode=>%s\nData=>%s", requestCode, resultCode, data);
}
// ****** Fm01中setResult调用,和Activity.setResult()类似 ******
setResult(setResult(RESULT_OK, "FragmentResultFrom[" + getClass().getSimpleName() + "]"));
finish();
运行图:
当然也可以同时启动多个Fragment来获取结果,此时在任一被此次操作启动并且处于显示状态的Fragment中进行setResult操作后返回启动页面就可返回结果
FragmentIntent intent01 = new FragmentIntent(Fm01.class).addFlag(FragmentIntent.FLAG_NEW_TASK);
FragmentIntent intent21 = new FragmentIntent(Fm21.class).addFlag(FragmentIntent.FLAG_NEW_TASK);
FragmentIntent intent23 = new FragmentIntent(Fm23.class);
startFragmentForResult(REQUEST_CODE, intent01, intent21, intent23);
//****** Fm21中setResult调用 ******
setResult(setResult(RESULT_OK, "FragmentResultFrom[" + getClass().getSimpleName() + "]"));
//参数1和2为Fm01和Fm21所在的task的id
getFragmentNav().finishTasks(1, 2);
运行图:
6、Activity.onSaveInstanceState() Safe
FragmentNav会自动保存在Activity.onSaveInstanceState()调用之后的对Fragment的操作并且在App被带回前台时执行操作
运行图:
集成
1、添加依赖
compile 'ray.easydev.fragmentnav:fragmentnav:0.1.2'
2、创建一个Activity继承FnFragmentActivity或FnAppCompatActivity,以继承FnFragmentActivity为例:
MainActivity.java
public class MainActivity extends FnFragmentActivity {
static {
//Configure the default fragment animations
FragmentIntent.getDefault().setAnim(
R.anim.page_start, //animation for start a fragment
R.anim.page_finish, //animation for finish a fragment
R.anim.page_show, //animation for show the previous fragment when finish a fragment
R.anim.page_hide //animation for hide the fragment when start a new fragment
);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public int getFragmentContainerId() {
//The id of ViewGroup that contains fragments
return R.id.fragment_container;
}
@NonNull
@Override
public FragmentIntent[] getStartIntents() {
//Configure the enter fragments
return new FragmentIntent[]{
//Configure the start fragment with activity intent's extras
new FragmentIntent(FmEnter.class, getIntent().getExtras())
//Disable the start animation to avoid the conflict with the activity's start animation
.addFlag(FragmentIntent.FLAG_NO_START_ANIMATION)
};
}
}
activity_main.xml
或者,你可以实现你自己的Activity,例如:
public class MyActivity extends FragmentActivity implements FnActivity {
private FragmentNav mFragmentNav;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//FragmentNav must be created before super.onCreate
mFragmentNav = FragmentNavHelper.createBeforeSuperOnCreate(this, R.id.fragment_container, savedInstanceState);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null){
//If this app is not in recovery, start a new fragment
mFragmentNav.startFragment(null, new FragmentIntent(FmEnter.class, getIntent().getExtras())
.addFlag(FragmentIntent.FLAG_NO_START_ANIMATION));
}
}
@NonNull
@Override
public FragmentNav getFragmentNav() {
return mFragmentNav;
}
@Override
public void onBackPressed() {
//Pass back pressed event to FragmentNav
FragmentNavHelper.onBackPressed(getFragmentNav());
}
}
3、继承FnFragment实现自己的Fragment
class FmEnter extends FnFragment {
}
单元测试
目前已经对主要实现逻辑进行了单元测试,结果如下,没有测试到的主要是一些Exception处理分支和一些暂未开放的功能,后续会尽量补上。
兼容性测试结果如下:
Android Sdk Version | Android Support Version |
---|---|
4.2.2, 4.4.4, 5.1, 6.0.1, 7.0 | 24.2.1, 25.3.0, 26.1.0 |
最后
如果FragmentNav给你带来了帮助,请给我一个Star以示支持吧