考虑到为了减少UI的'刷新效果',EL使用Fragment来代替常规的Activity方式.
Fragment代替Activity的好处很多,比如没有不同UI间切换的'闪动',视觉是上也有加快显示的效果.但这种效果也是有代价的, 大量Activity方式下的工作,在Fragment时,不得不自己来实现,比如UI的'压栈'等等.
这里记录下EL实现中,碰到的跟Fragment相关的问题. (Fragment相关文档的
官方链接在这里)
1. 参数传递
Activity切换时,可以在StartActivity()时,通过Intent的方式将所需参数传递给下一个Activity. 但在Fragment方式下就不行了,此时可使用/参考Fragment支持的setArguments()和getArguments(). EL中所有Fragment都继承于BaseFragment,在显示Fragment时,使用设计的OnArgument()接口传递参数.
fragment.onArguments(args);
fragmentManager.beginTransaction().show(fragment).commit();
2. 界面切换
FragmentManager是用于管理Fragment的类,通过内部的FragmentTranscation对象实现Fragment的加载/显示/隐藏/移除等操作. EL实现中,使用FragmentSwitcher类封装了FrangmentManager,以实现某些更灵活的Fragment管理,比如某些Fragment在被切换是需要删除,而其他的仅需要隐藏等操作.
public enum Type {
LIST("list", false), SHOW("show", false), ABOUT("about", true), SETTING("setting", true),
DOWNLOAD("download", true);
private final String title;
private final boolean removed;
private Type(final String title, boolean removed) {
this.title = title;
this.removed = removed;
}
public String getTitle() {
return title;
}
public boolean hasRemoved() {
return removed;
}
public static Type getType(final String title) {
if (title.equals(LIST.getTitle())) {
return LIST;
} else if (title.equals(SHOW.getTitle())) {
return SHOW;
} else {
return null;
}
}
}
public boolean show(Type type, Bundle args) {
if (curType != null) {
if (curType == type) {
((BaseFragment) fragmentManager.findFragmentByTag(type.getTitle())).onArguments(args);
return true;
} else {
hide(curType);
}
}
BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(type.getTitle());
if (fragment == null) {
fragment = create(type);
if (fragment == null) {
return false;
}
}
fragment.onArguments(args);
fragmentManager.beginTransaction().show(fragment).commit();
curType = type;
return true;
}
3. Fragment的栈
Activity在切换时,通常情况下可以通过BACK键返回前一个Activity,是因为存在一个'栈'来存放前面的Activity. Fragment也有栈的概念,但在操作上就需要自己主动调用了 -- Fragment隐藏时,压栈; Fragment退出时,出栈.
private void hide(Type type) {
BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(type.getTitle());
if (fragment != null) {
if (type.hasRemoved()) {
fragmentManager.beginTransaction().remove(fragment).commit();
} else {
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.addToBackStack(type.getTitle());
ft.hide(fragment);
ft.commit();
// fragmentManager.beginTransaction().hide(fragment).commit();
}
curType = null;
}
}
public boolean showPrevFragment() {
int count = fragmentManager.getBackStackEntryCount();
if (count > 0) {
String name = fragmentManager.getBackStackEntryAt(count - 1).getName();
fragmentManager.popBackStack();// .popBackStackImmediate();
Type type = Type.getType(name);
if (type != null) {
show(type);
return true;
}
}
return false;
}
总的来说,Fragment要想用着方便,自己使用FragmentSwitcher和BaseFragment来封装下FragmentManager和Fragment还是不错的选择.
Fragment看起来很美,用起来真是发疯啊.上面这些都是实现EL中碰到的问题,这里做下记录,怕回头又忘记'痛苦地翻文档'的日子...
另,EL基本完工,这两天可发布Alpha版了...