我有3个片段(A,B和C)的活动。片段A已添加到活动onCreate
中,但也未添加到backstack
。
此活动的导航流程可以是:
A - > B - > C,或 A - > ç
在片段B或C上按回或navigateUp
应返回上一个片段。
将片段添加到活动的代码是:
private void switchFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container_fragments, fragment, fragment.getClass().getSimpleName());
if (addToBackStack) {
ft.addToBackStack(null);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
currentFragment = fragment;
}
获取当前片段的代码是:
private Fragment getCurrentFragment(){
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() == 0)
return null;
String tag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName();
return getFragmentManager().findFragmentByTag(tag);
}
我覆盖onBackPressed
和onNavigateUp
如下:
@Override
public void onBackPressed() {
super.onBackPressed();
currentFragment = getCurrentFragment();
if (currentFragment == null) {
currentFragment = fragmentA;
}
setHeader();
}
@Override
public boolean onNavigateUp() {
if (currentFragment == fragmentA) {
return super.onNavigateUp();
}
else {
getFragmentManager().popBackStack();
currentFragment = getCurrentFragment();
if (currentFragment == null) {
currentFragment = fragmentA;
}
setHeader();
return true;
}
}
setHeader
是一种根据显示的当前片段更改活动标题文本的方法。
如果我从A导航到C并向后导航,则上述工作正常。但是,从A到B导航到C并向后导航不起作用。当从C返回到B时,代码认为它已经在A上(显示A的标题文本),但是正在显示片段B.
以上不是处理后台堆的正确方法吗?我做错了什么?
答案 0 :(得分:0)
此代码表现良好,您可以查看一次。 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);
//Toast.makeText(getApplicationContext(), "Hi", Toast.LENGTH_SHORT).show();
}else{
ft.setCustomAnimations(0, 0);
}
ft.replace(R.id.frame_container, fragment);
ft.commit();
// Toast.makeText(getApplicationContext(), "+"+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show();
}
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
//Toast.makeText(getApplicationContext(), ""+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show();
Fragment fragment = mStacks.get(mCurrentNavigatorMenu).elementAt(mStacks.get(mCurrentNavigatorMenu).size() - 2);
/* pop current fragment from stack.. */
mStacks.get(mCurrentNavigatorMenu).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.frame_container, fragment);
ft.commit();
}
@Override
public void onBackPressed() {
if (((BaseFragment) mStacks.get(mCurrentNavigatorMenu).lastElement())
.onBackPressed() == false) {
/*
* 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(mCurrentNavigatorMenu).size() == 1) {
super.onBackPressed();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);// or call finish..
} else {
popFragments();
}
} else {
// do nothing.. fragment already handled back button press.
Toast.makeText(getApplicationContext(), "Nothing", Toast.LENGTH_LONG).show();
}
}
答案 1 :(得分:0)
以上代码适用于导航。我删除了setHeader
方法并将其移到此处:
final FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
Fragment fr = fm.findFragmentById(R.id.container_fragments);
if(fr!=null){
currentFragment = fr;
setTitle();
}
}
});
这样我知道当前正在显示哪个片段并设置标题 相应