Android中TabHost中每个片段的自定义后堆栈
由于TabActivity已被弃用,我试图用开发人员android网站中已经提到的片段替换它。但正如你们已经知道的,用片段替换标签有一个问题,因为只有一个活动,那就是片段活动,每个片段都没有后台堆栈,正如您在另一个片段中所看到的,因此大多数开发人员的问题是,您需要管理自己的自定义后台堆栈作为解决方案 我已经创建并实现了我自己的自定义后台堆栈,正如您在下面看到的,它工作得非常完美,我可以跟踪每个选项卡中的每个片段 表1 表2 根据上面的导航,如果我从Fragment1导航到Fragment3,然后如果我将选项卡更改为Tab2并返回到Tab1,我仍然可以看到Fragment3,甚至可以使用我的自定义后堆栈导航回Fragment1 但问题是,当我回到Tab1并看到Fragment3时,Fragment3被重新创建,我无法看到我在将tab更改为Tab2之前留下的更改 这是我的自定义后堆栈Android中TabHost中每个片段的自定义后堆栈,android,android-fragments,android-tabhost,Android,Android Fragments,Android Tabhost,由于TabActivity已被弃用,我试图用开发人员android网站中已经提到的片段替换它。但正如你们已经知道的,用片段替换标签有一个问题,因为只有一个活动,那就是片段活动,每个片段都没有后台堆栈,正如您在另一个片段中所看到的,因此大多数开发人员的问题是,您需要管理自己的自定义后台堆栈作为解决方案 我已经创建并实现了我自己的自定义后台堆栈,正如您在下面看到的,它工作得非常完美,我可以跟踪每个选项卡中的每个片段 表1 表2 根据上面的导航,如果我从Fragment1导航到Fragment3,然后
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);
}