2

正如我们所知,ActivityGroup 已被弃用。我正在尝试重新配置我的代码。

此代码使用 ActivityGroup :

public void lauchContentActivity(Intnet intent) {
    View view = getLocationActivityManager().startActivity(
            intent.getComponent().getShortClassName(),
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
            .getDecorView();
    setContentView(view);
}

所以我可以调整任何活动的可见性,并保存隐藏的活动实例状态。

但是 FragmentManager 只有一个 backstack,并且不能将 Fragment 带到前面,除非按下 Back 按钮。

如何像ActivityGroup manager Activity一样管理Fragment?

4

2 回答 2

2

这个答案的可行性将取决于你想通过不同的活动来完成什么。我有一个类似的问题,我通过使用Fragments. 想象一下,您有一个Activity具有不同方面的任务。然后,您可以轻松地使用Activity来收集和保存您需要的数据,Fragment或者提供您的业务逻辑,并且您Fragment的 s 可以满足任务的不同方面。我强烈推荐这个Fragment并且FragmentManager应该替换已弃用的ActivityGroup. 以下是有关此事的一些文档:

现在,使用Fragments 与使用有点不同,Activity但差别不大。基本上,你声明你Fragment喜欢任何其他对象。为了向您展示您Fragment 将使用:

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
YourFragment yourFragment = new YourFragment();
fragmentTransaction.replace(R.id.containerID, yourFragment);
fragmentTransaction.addToBackStack();
fragmentTransaction.commit();

您可以使用 ADK 下载的文档还包含许多使用Fragments 的示例。如果您想获得一些高质量的代码片段,我相信这是一个好的开始!

于 2013-07-30T06:22:01.210 回答
2

我实现了片段选项卡,在添加和删除片段时实现和理解片段层次结构对我来说是一个挑战。

作为管理问题fragments,这取决于您的要求,示例详细说明了片段的层次结构以及在 HashMap 的帮助下管理片段的方式。

下面的课程将向您解释片段的行为。(该样本中存在的类)

AppMainTabActivity.java

public class AppMainTabActivity extends FragmentActivity {
    /* Your Tab host */
    private TabHost mTabHost;

    /* A HashMap of stacks, where we use tab identifier as keys.. */
    private HashMap<String, Stack<Fragment>> mStacks;

    /* Save current tabs identifier in this.. */
    private String mCurrentTab;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.app_main_tab_fragment_layout);

        /*
         * Navigation stacks for each tab gets created.. tab identifier is used
         * as key to get respective stack for each tab
         */
        mStacks = new HashMap<String, Stack<Fragment>>();
        mStacks.put(AppConstants.TAB_A, new Stack<Fragment>());
        mStacks.put(AppConstants.TAB_B, new Stack<Fragment>());
        mStacks.put(AppConstants.TAB_C, new Stack<Fragment>());

        mTabHost = (TabHost) findViewById(android.R.id.tabhost);
        mTabHost.setOnTabChangedListener(listener);
        mTabHost.setup();

        initializeTabs();
    }

    private View createTabView(final int id) {
        View view = LayoutInflater.from(this).inflate(R.layout.tabs_icon, null);
        ImageView imageView = (ImageView) view.findViewById(R.id.tab_icon);
        imageView.setImageDrawable(getResources().getDrawable(id));
        return view;
    }

    public void initializeTabs() {
        /* Setup your tab icons and content views.. Nothing special in this.. */
        TabHost.TabSpec spec = mTabHost.newTabSpec(AppConstants.TAB_A);
        mTabHost.setCurrentTab(-3);
        spec.setContent(new TabHost.TabContentFactory() {
            public View createTabContent(String tag) {
                return findViewById(R.id.realtabcontent);
            }
        });

        spec.setIndicator(createTabView(R.drawable.toolkittabicon));
        mTabHost.addTab(spec);

        spec = mTabHost.newTabSpec(AppConstants.TAB_B);
        spec.setContent(new TabHost.TabContentFactory() {
            public View createTabContent(String tag) {
                return findViewById(R.id.realtabcontent);
            }
        });
        spec.setIndicator(createTabView(R.drawable.followtabicon));
        mTabHost.addTab(spec);

        spec = mTabHost.newTabSpec(AppConstants.TAB_C);
        spec.setContent(new TabHost.TabContentFactory() {
            public View createTabContent(String tag) {
                return findViewById(R.id.realtabcontent);
            }
        });
        spec.setIndicator(createTabView(R.drawable.myhuddletabicion));
        mTabHost.addTab(spec);
    }

    /* Comes here when user switch tab, or we do programmatically */
    TabHost.OnTabChangeListener listener = new TabHost.OnTabChangeListener() {
        public void onTabChanged(String tabId) {
            /* Set current tab.. */
            mCurrentTab = tabId;

            if (mStacks.get(tabId).size() == 0) {
                /*
                 * First time this tab is selected. So add first fragment of
                 * that tab. Dont need animation, so that argument is false. We
                 * are adding a new fragment which is not present in stack. So
                 * add to stack is true.
                 */
                if (tabId.equals(AppConstants.TAB_A)) {
                    pushFragments(tabId, new ToolKitFragment(), false, true);
                } else if (tabId.equals(AppConstants.TAB_B)) {
                    pushFragments(tabId, new FollowFragment(), false, true);
                } else if (tabId.equals(AppConstants.TAB_C)) {
                    pushFragments(tabId, new HuddleFragment(), false, true);
                }
            } else {
                /*
                 * We are switching tabs, and target tab is already has atleast
                 * one fragment. No need of animation, no need of stack pushing.
                 * Just show the target fragment
                 */
                pushFragments(tabId, mStacks.get(tabId).lastElement(), false,
                        false);
            }
        }
    };

    /*
     * Might be useful if we want to switch tab programmatically, from inside
     * any of the fragment.
     */
    public void setCurrentTab(int val) {
        mTabHost.setCurrentTab(val);
    }

    /*
     * To add fragment to a tab. tag -> Tab identifier fragment -> Fragment to
     * show, in tab identified by tag shouldAnimate -> should animate
     * transaction. false when we switch tabs, or adding first fragment to a tab
     * true when when we are pushing more fragment into navigation stack.
     * shouldAdd -> Should add to fragment navigation stack (mStacks.get(tag)).
     * false when we are switching tabs (except for the first time) true in all
     * other cases.
     */
    public void pushFragments(String tag, Fragment fragment,
            boolean shouldAnimate, boolean shouldAdd) {
        if (shouldAdd)
            mStacks.get(tag).push(fragment);
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        if (shouldAnimate)
            ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
        ft.replace(R.id.realtabcontent, fragment);
        ft.commit();
    }

    public void popFragments() {
        /*
         * Select the second last fragment in current tab's stack.. which will
         * be shown after the fragment transaction given below
         */
        Fragment fragment = mStacks.get(mCurrentTab).elementAt(
                mStacks.get(mCurrentTab).size() - 2);

        /* pop current fragment from stack.. */
        mStacks.get(mCurrentTab).pop();

        /*
         * We have the target fragment in hand.. Just show it.. Show a standard
         * navigation animation
         */
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction ft = manager.beginTransaction();
        ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
        ft.replace(R.id.realtabcontent, fragment);
        ft.commit();
    }

    @Override
    public void onBackPressed() {
        if (((BaseFragment) mStacks.get(mCurrentTab).lastElement())
                .onBackPressed() == false) {
            Log.d("######", "on back press");
            /*
             * top fragment in current tab doesn't handles back press, we can do
             * our thing, which is
             * 
             * if current tab has only one fragment in stack, ie first fragment
             * is showing for this tab. finish the activity else pop to previous
             * fragment in stack for the same tab
             */
            if (mStacks.get(mCurrentTab).size() == 1) {
                super.onBackPressed(); // or call finish..
            } else {
                popFragments();
            }
        } else {
            // do nothing.. fragment already handled back button press.
        }
    }

    /*
     * Imagine if you wanted to get an image selected using ImagePicker intent
     * to the fragment. Ofcourse I could have created a public function in that
     * fragment, and called it from the activity. But couldn't resist myself.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mStacks.get(mCurrentTab).size() == 0) {
            return;
        }

        /* Now current fragment on screen gets onActivityResult callback.. */
        mStacks.get(mCurrentTab).lastElement()
                .onActivityResult(requestCode, resultCode, data);
    }
}

但是,如果您有子片段,那么它将在该示例中未处理的背压上产生问题,解决方案@您必须覆盖 onDetach()方法并管理代码片段下方的子片段检查。

@Override
    public void onDetach() {
        super.onDetach();
         try {
                Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
                childFragmentManager.setAccessible(true);
                childFragmentManager.set(this, null);

            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
    }

另外参考开发者网站并详细挖掘片段

于 2013-07-31T06:47:17.413 回答