在以下情况下,为什么FragmentTwo
会从后台消失:
Fragment
中有一个名为FragmentOne
的{{1}}。Activity
拥有FragmentOne
。单击时,它会启动Button
,并将其添加到FragmentTwo
后台堆栈中。 Fragment
有一个FragmentTwo
,点击后会为与Button
,ActionBar
和Fragments
相关联的FragmentThree
添加两个标签。 FragmentFour
可见。 FragmentThree
。相反,我看到FragmentTwo
。 FragmentOne
去了哪里? 在我覆盖FragmentTwo
并开始为onKeyDown()
开始实施我自己的后台包装之前,我想问一下我是否遗漏了一些明显的东西?请注意,测试时没有发生配置更改。
详细说明:
FragmentOne的按钮点击处理程序包含:
Fragments
FragmentTwo按钮单击在Activity:
中处理 FragmentTransaction ft = getFragmentManager().beginTransaction();
FragmentTwo fragment = new FragmentTwo();
ft.addToBackStack(null);
ft.replace(android.R.id.content, fragment).commit();
标签监听器的位置是:
getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
FragmentFour fragmentThree = new FragmentThree();
FragmentFive fragmentFive = new FragmentFive();
ActionBar.Tab tab = getActionBar().newTab().setText("Frag 3").setTabListener(new CustomTabListener<FragmentThree>(fragmentThree));
getActionBar().addTab(tab);
tab = getActionBar().newTab().setText("Frag 4").setTabListener(new CustomTabListener<FragmentFour>(fragmentFour));
getActionBar().addTab(tab);
如果在显示public static class CustomTabListener<T extends Fragment> implements TabListener {
Fragment fragment;
public CustomTabListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(android.R.id.content, fragment);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
之前向backstack添加更多Fragments
,则始终只有FragmentThree
之前Fragment
消失。
当我通过按后退键离开选项卡式用户视图并返回FragmentThree
时,标签仍然显示。我了解到我需要将FragmentOne
重置为ActionBar
,但不清楚为什么显示NAVIGATION_MODE_STANDARD
而不是FragmentOne
。
答案 0 :(得分:2)
我认为问题在于你是否构建了标签
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(android.R.id.content, fragment);
}
调用并将之前的片段添加到backstack
你打算试试吗?ft.addToBackStack(null);
在Fragment Two按钮处理代码中。
但是你需要实现onBackPressed()
来摆脱标签。我想我会用标签进行新的活动。
答案 1 :(得分:2)
public class StartActivity extends SherlockFragmentActivity implements
TabListener, OnBackStackChangedListener {
private Context mContext = null;
private ActionBar mActionBar;
private Tab mTab;
private Fragment mSelectFragment;
private final static int ONE = 0;
private final static int TWO = 1;
private final static int THREE = 2;
private final static int PLAYERS = 3;
private MenuItem mPlayerItem = null;
private FragmentTransaction mFragmentTransaction = null;
/**
* by default is false - TABS were taken in the starting true - when we are
* changing back to TABS from STANDARD
*/
private boolean mTabsChanges = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mContext = this;
mActionBar = getSupportActionBar();
// hiding the ActionBar icon
mActionBar.setDisplayShowHomeEnabled(true);
// for displaying the Arrow button
mActionBar.setDisplayHomeAsUpEnabled(true);
// hide Actionbar title
mActionBar.setDisplayShowTitleEnabled(true);
// Create Actionbar Tabs
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create first Tab
mTab = mActionBar.newTab().setTabListener(this);
mTab.setText("One");
mActionBar.addTab(mTab);
// Create Second Tab
mTab = mActionBar.newTab().setTabListener(this);
mTab.setText("Two");
mActionBar.addTab(mTab);
// Create Three Tab
mTab = mActionBar.newTab().setTabListener(this);
mTab.setText("Three");
mActionBar.addTab(mTab);
getSupportFragmentManager().addOnBackStackChangedListener(this);
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mFragmentTransaction = ft;
if (mTabsChanges) {
// nothing to do here
mTabsChanges = false;
} else {
switch (mActionBar.getSelectedNavigationIndex()) {
case ONE:
clearBackStack(mTabsChanges);
mSelectFragment = new Fragment1();
ft.replace(R.id.fragment_container, mSelectFragment, ONE + "");
break;
case TWO:
clearBackStack(mTabsChanges);
mSelectFragment = new Fragment2();
ft.replace(R.id.fragment_container, mSelectFragment, TWO + "");
break;
case THREE:
clearBackStack(mTabsChanges);
mSelectFragment = new Fragment3();
ft.replace(R.id.fragment_container, mSelectFragment, THREE + "");
break;
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(
mContext,
"tab unselected." + mActionBar.getSelectedNavigationIndex()
+ "", Toast.LENGTH_SHORT).show();
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(
mContext,
"tab reselected." + mActionBar.getSelectedNavigationIndex()
+ "", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater mInflate = getSupportMenuInflater();
mInflate.inflate(R.menu.header_menu, menu);
mPlayerItem = menu.findItem(R.id.men_set_players);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.men_set_players) {
addFragmentToStack();
return true;
}
return false;
}
private void addFragmentToStack() {
// Add the fragment to the activity, pushing this transaction
// on to the back stack.
mActionBar.setTitle(getResources().getString(R.string.menu_players));
mSelectFragment = new PlayersFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, mSelectFragment, "Players");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack("players");
ft.commit();
}
@Override
public void onBackStackChanged() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
int TOP = fm.getBackStackEntryCount() - 1;
Log.i("BACKSTACK", TOP + ".."
+ fm.getBackStackEntryAt(TOP).getName());
if (fm.getBackStackEntryAt(TOP).getName()
.equalsIgnoreCase("players")) {
if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
mTabsChanges = false;
mActionBar
.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
} else {
if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
mTabsChanges = true;
mActionBar
.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
}
} else {
if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
mTabsChanges = true;
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
} else if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
mTabsChanges = false;
}
}
Toast.makeText(mContext,
"FM Back count." + fm.getBackStackEntryCount(),
Toast.LENGTH_SHORT).show();
}
public void clearBackStack(boolean callFromSelection) {
if (!callFromSelection) {
FragmentManager fm = getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
fm.popBackStackImmediate();
}
} else {
Toast.makeText(mContext, "callfromreapprearence",
Toast.LENGTH_SHORT).show();
}
}
}
答案 2 :(得分:1)
始终使用此代码块替换片段:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.content, YOUR_FRAGMENT);
ft.addToBackStack(null);
ft.commit();
答案 3 :(得分:1)
我认为您需要删除ft.remove
函数中的onTabUnselected()
,因为替换已经执行此操作。
答案 4 :(得分:1)
根据您上面显示的代码,您永远不会将Fragment2添加到后台堆栈。
@gabe,@ Piier,API http://developer.android.com/reference/android/app/ActionBar.TabListener.html
中记录了在侦听器中使用addToBackStack()
获取IllegalStateException的原因
public abstract void onTabSelected (ActionBar.Tab tab, FragmentTransaction ft)
在API级别11中添加
当标签进入选定状态时调用。
“参数”选项卡已选择的选项卡
ft FragmentTransaction,用于排序在选项卡切换期间执行的片段操作。上一个选项卡未选中,此选项卡的选择将在单个事务中执行。
此FragmentTransaction不支持添加到后台堆栈。
解决这个问题的简单方法是使用FragmentManager在TabListener中创建自己的FragmentTransaction并将其添加到后台堆栈。像这样的东西
public static class CustomTabListener<T extends Fragment> implements TabListener {
Fragment fragment;
public CustomTabListener(Fragment fragment) {
this.fragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
FragmentManager fm = getFragmentManager();
FragmentTransaction newFragTrans = fm.beginTransaction();
newFragTrans.replace(android.R.id.content, fragment);
newFragTrans.addToBackStack(null);
newFragTrans.commit()
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
我只修改了onTabSelected,但你明白了。此外,请不要忘记commit()
此交易,因为听众只会自动commit()
提供的FragmentTransaction ft
最后一件事,确保在执行事务后调用addToBackStack()
,因为这是您要添加到堆栈的内容,而不是实际的片段。在上面的代码中,没有为Fragment1的按钮单击完成。
希望这有帮助。