Custom Back Stack for each Fragment in TabHost in Android

孤者浪人 提交于 2019-11-27 21:41:51

I modified googles sample tablistener to following:

public static class TabListener<T extends SherlockFragment> implements ActionBar.TabListener {
    private final SherlockFragmentActivity mActivity;
    private final String mTag;
    private final Class<T> mClass;
    private final Bundle mArgs;
    public SherlockFragment mFragment;
    private final Stack<SherlockFragment> mStack;

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
        this(activity, tag, clz, null, null);
    }

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz, Bundle args, Stack<SherlockFragment> stack) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
        mArgs = args;
        mStack = stack;

        // Check to see if we already have a fragment for this tab, probably
        // from a previously saved state.  If so, deactivate it, because our
        // initial state is that a tab isn't shown.
        mFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
        if (mFragment != null && !mFragment.isDetached()) {
            FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
            ft.detach(mFragment);
            ft.commit();
        }
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // we need to reattach ALL fragments thats in the custom stack, if we don't we'll have problems with setCustomAnimation for fragments.
        if (mFragment == null) {
            mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName(), mArgs);
            ft.replace(android.R.id.content, mFragment, mTag);
        } else {
            ft.attach(mFragment);
        }
        if(mStack != null) {
            for(SherlockFragment fragment: mStack) {
                ft.attach(fragment);
            }
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.detach(mFragment);
        }
        if(mStack != null) {
            for(SherlockFragment fragment: mStack) {
                if(fragment!= null && !fragment.isDetached()) {
                    ft.detach(fragment);
                }
            }
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}

And the activity onKeyDown methode I override to following:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        int index = getSupportActionBar().getSelectedNavigationIndex();
        Stack<SherlockFragment> stack = null;
        SherlockFragment fragment = null;
        String rootTag = null;
        switch(index) {
            case 0:
                stack = mWatersTabListener.mStack;
                fragment = mWatersTabListener.mFragment;
                rootTag = mWatersTabListener.mTag;
                break;
            case 1:
                stack = mHarborTabListener.mStack;
                fragment = mHarborTabListener.mFragment;
                rootTag = mHarborTabListener.mTag;
                break;
        }

        if(stack.isEmpty()) {
            return super.onKeyDown(keyCode, event);
        } else {
            SherlockFragment topFragment = stack.pop();
            FragmentManager fragmentManager = getSupportFragmentManager();

            FragmentTransaction ft = fragmentManager.beginTransaction();

            ft.setCustomAnimations(R.anim.fragment_slide_right_enter,
                    R.anim.fragment_slide_right_exit);

            if(topFragment != null && !topFragment.isDetached()) {
                ft.detach(topFragment);
            }

            if(stack.isEmpty()) {
                ft.replace(android.R.id.content, fragment, rootTag);
                ft.commit();
                return true;
            } else {
                SherlockFragment nextFragment = stack.peek();
                ft.replace(android.R.id.content, nextFragment);
                ft.commit();
                return true;
            }
        }
    }
    return super.onKeyDown(keyCode, event);
}

The important things to take note of is that you have to attach all fragments in your custom stack when selected and you have to detach all as well when unselected. If there is problem with understanding the code snippets just ask.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!