Android中TabHost中每个片段的自定义后堆栈

Android中TabHost中每个片段的自定义后堆栈,android,android-fragments,android-tabhost,Android,Android Fragments,Android Tabhost,由于TabActivity已被弃用,我试图用开发人员android网站中已经提到的片段替换它。但正如你们已经知道的,用片段替换标签有一个问题,因为只有一个活动,那就是片段活动,每个片段都没有后台堆栈,正如您在另一个片段中所看到的,因此大多数开发人员的问题是,您需要管理自己的自定义后台堆栈作为解决方案 我已经创建并实现了我自己的自定义后台堆栈,正如您在下面看到的,它工作得非常完美,我可以跟踪每个选项卡中的每个片段 表1 表2 根据上面的导航,如果我从Fragment1导航到Fragment3,然后

由于TabActivity已被弃用,我试图用开发人员android网站中已经提到的片段替换它。但正如你们已经知道的,用片段替换标签有一个问题,因为只有一个活动,那就是片段活动,每个片段都没有后台堆栈,正如您在另一个片段中所看到的,因此大多数开发人员的问题是,您需要管理自己的自定义后台堆栈作为解决方案

我已经创建并实现了我自己的自定义后台堆栈,正如您在下面看到的,它工作得非常完美,我可以跟踪每个选项卡中的每个片段

表1

表2

根据上面的导航,如果我从Fragment1导航到Fragment3,然后如果我将选项卡更改为Tab2并返回到Tab1,我仍然可以看到Fragment3,甚至可以使用我的自定义后堆栈导航回Fragment1

但问题是,当我回到Tab1并看到Fragment3时,Fragment3被重新创建,我无法看到我在将tab更改为Tab2之前留下的更改

这是我的自定义后堆栈

public static HashMap<String, Stack<Fragment>> customBackStack;

public static Stack<Fragment> simpleStack;
public static Stack<Fragment> contactStack;
public static Stack<Fragment> customStack;
public static Stack<Fragment> throttleStack;
public static Stack<Fragment> homeStack;

customBackStack = new HashMap<String, Stack<Fragment>>();

homeStack = new Stack<Fragment>();
simpleStack = new Stack<Fragment>();
contactStack = new Stack<Fragment>();
customStack = new Stack<Fragment>();
throttleStack = new Stack<Fragment>();

customBackStack.put("home", homeStack);
customBackStack.put("simple", simpleStack);
customBackStack.put("contacts", contactStack);
customBackStack.put("custom", customStack);
customBackStack.put("throttle", throttleStack);
这里是反压的

    public void onBackPressed() {

    Stack<Fragment> stack = customBackStack.get(mTabHost.getCurrentTabTag());

    if (stack.isEmpty()) {
        super.onBackPressed();
    } else {

        Fragment fragment = stack.pop();

        if (fragment.isVisible()) {
            if (stack.isEmpty()) {
                super.onBackPressed();
            } else {
                Fragment frg = stack.pop();
                customBackStack.get(mTabHost.getCurrentTabTag()).push(frg);

                transaction = getSupportFragmentManager().beginTransaction();
                transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right,
                        R.anim.slide_in_right, R.anim.slide_out_left);

                transaction.replace(R.id.realtabcontent, frg).commit();
            }
        } else {
            getSupportFragmentManager().beginTransaction().replace(R.id.realtabcontent, fragment).commit();
        }
    }

}
public void onBackPressed(){
Stack Stack=customBackStack.get(mTabHost.getCurrentTabTag());
if(stack.isEmpty()){
super.onBackPressed();
}否则{
Fragment Fragment=stack.pop();
if(fragment.isVisible()){
if(stack.isEmpty()){
super.onBackPressed();
}否则{
Fragment frg=stack.pop();
customBackStack.get(mTabHost.getCurrentTabTag()).push(frg);
事务=getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide\u in\u left,R.anim.slide\u out\u right,
R.anim.滑入(右),R.anim.滑出(左);
transaction.replace(R.id.realtabcontent,frg).commit();
}
}否则{
getSupportFragmentManager().beginTransaction().replace(R.id.realtabcontent,fragment.commit();
}
}
}
因此,自定义后堆栈可以正常工作,除了更改选项卡之前的最后一个片段在返回到选项卡后被重新创建,它不会像在选项卡活动中一样恢复

你知道怎么解决吗

编辑

您可以在这里找到我的示例应用程序,作为有关此问题的解决方案


我将谷歌样本列表器修改为:

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) {
    }
}
@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);
}
公共静态类TabListener实现ActionBar.TabListener{
私人最终SherlockFragmentActivity;
私有最终字符串mTag;
私人期末班;
私人最终捆绑保证金;
公共夏洛克区;
私有最终堆栈mStack;
公共TabListener(SherlockFragmentActivity活动,字符串标记,类clz){
这(活动、标记、clz、null、null);
}
公共TabListener(SherlockFragmentActivity活动、字符串标记、类clz、捆绑参数、堆栈){
活动性=活动性;
mTag=标签;
mClass=clz;
mArgs=args;
mStack=堆栈;
//检查一下,看看我们是否已经有了这个标签的一个片段,可能吧
//从以前保存的状态。如果是,请将其停用,因为
//初始状态是不显示选项卡。
MFFragment=(SherlockFragment)mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if(mffragment!=null&&!mffragment.isDetached()){
FragmentTransaction ft=MacActivity.getSupportFragmentManager().beginTransaction();
ft.分离(mFragment);
ft.commit();
}
}
已选择的公共事务(选项卡,碎片事务ft){
//我们需要重新附加自定义堆栈中的所有片段,如果我们不这样做,我们将在setCustomAnimation for fragments中遇到问题。
if(mFragment==null){
MFFragment=(SherlockFragment)SherlockFragment.instantiate(mActivity,mClass.getName(),mArgs);
ft.replace(android.R.id.content、mFragment、mTag);
}否则{
ft.attach(mFragment);
}
if(mStack!=null){
for(夏洛克碎片:mStack){
ft.attach(片段);
}
}
}
已选择公共空页(选项卡,碎片事务ft){
if(mFragment!=null){
ft.分离(mFragment);
}
if(mStack!=null){
for(夏洛克碎片:mStack){
if(fragment!=null&&!fragment.isDetached()){
ft.分离(碎片);
}
}
}
}
已重新选择公共无效页签(页签,碎片事务){
}
}
而活动onKeyDown方法我覆盖到以下内容:

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) {
    }
}
@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);
}
@覆盖
公共布尔onKeyDown(int-keyCode,KeyEvent事件){
if(keyCode==KeyEvent.keyCode\u BACK){
int index=getSupportActionBar().getSelectedNavigationIndex();
Stack=null;
SherlockFragment=null;
字符串rootTag=null;
开关(索引){
案例0:
stack=mWatersTabListener.mStack;
fragment=mWatersTabListener.mFragment;
rootTag=mWatersTabListener.mTag;
打破
案例1:
stack=mHarborTabListener.mStack;
fragment=mHarborTabListener.mffragment;
rootTag=mHarborTabListener.mTag;
打破
}
if(stack.isEmpty()){
返回super.onKeyDown(keyCode,event);
}否则{
SherlockFragment-topFragment=stack.pop();
FragmentManager FragmentManager=getSupportFragmentManager();
FragmentTransaction ft=fragmentManager.beginTransaction();
ft.setCustomAnimations(R.anim.fragme
@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);
}