Codejie's C++ Space

Using C++

EL : Fragment and FragmentManager


    考虑到为了减少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版了...

posted on 2013-08-11 10:08 codejie 阅读(1850) 评论(0)  编辑 收藏 引用 所属分类: 随笔而已G7


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜