Android 碎片从背面消失
为什么在以下情况下,Android 碎片从背面消失,android,android-fragments,android-actionbar,android-tabs,Android,Android Fragments,Android Actionbar,Android Tabs,为什么在以下情况下,FragmentTwo会从后台消失: 我的应用程序在活动中有一个名为FragmentOne的片段 FragmentOne持有一个按钮。单击后,它将启动FragmentTwo,并将其添加到Fragmentbackstack中 FragmentTwo有一个按钮,单击该按钮时,会在操作栏中添加两个选项卡,链接到两个片段,FragmentThree和FragmentFour碎片三可见 如果我现在单击后退按钮,我希望看到FragmentTwo。相反,我看到的是FragmentOne。
FragmentTwo
会从后台消失:
- 我的应用程序在
活动中有一个名为
的FragmentOne
片段
持有一个FragmentOne
。单击后,它将启动按钮
,并将其添加到FragmentTwo
backstack中李>Fragment
有一个FragmentTwo
,单击该按钮时,会在按钮
中添加两个选项卡,链接到两个操作栏
,片段
和FragmentThree
<代码>碎片三可见李>FragmentFour
- 如果我现在单击后退按钮,我希望看到
。相反,我看到的是FragmentTwo
。FragmentOne
去了哪里李>FragmentTwo
onKeyDown()
并开始为片段实现我自己的backbackback之前,我想问一下是否有明显的遗漏?注意:测试时没有发生配置更改
详情:
FragmentOne的按钮单击处理程序包含:
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);
getActionBar().setNavigationMode(ActionBar.NAVIGATION\u MODE\u选项卡);
FragmentFour fragmentThree=新的fragmentThree();
FragmentFive FragmentFive=新的FragmentFive();
ActionBar.Tab Tab=getActionBar().newTab().setText(“Frag3”).setTableListener(新的CustomTableListener(fragmentThree));
getActionBar().addTab(选项卡);
tab=getActionBar().newTab().setText(“碎片4”).setTableListener(新的CustomTableListener(碎片四));
getActionBar().addTab(选项卡);
其中选项卡侦听器是:
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) {
}
}
public静态类CustomTabListener实现了TabListener{
片段;
公共CustomTableListener(片段){
this.fragment=片段;
}
已选择的公共事务(选项卡,碎片事务ft){
ft.replace(android.R.id.content,fragment);
}
已选择公共空页(选项卡,碎片事务ft){
ft.去除(碎片);
}
已重新选择公共无效页签(页签,碎片事务){
}
}
如果在显示FragmentThree
之前向backstack添加更多FragmentThree
,则始终且仅FragmentThree
之前的片段
消失
当我按back键离开选项卡式用户视图并返回到FragmentOne
时,选项卡仍在显示。我知道我需要将ActionBar
重置为NAVIGATION\u MODE\u STANDARD
,但不清楚为什么显示FragmentOne
而不是FragmentTwo
,我认为问题在于是否构建了选项卡
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(android.R.id.content, fragment);
}
调用,并且之前的片段未添加到backback
你试过打电话吗
ft.addToBackStack(null);
在片段中有两个按钮处理代码
但无论如何,您都需要实现onBackPressed()
以摆脱选项卡。我想我应该使用选项卡创建新活动。始终使用此代码块替换片段:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.content, YOUR_FRAGMENT);
ft.addToBackStack(null);
ft.commit();
我认为您需要删除onTabUnselected()
函数中的ft.remove
,因为replace已经这样做了。根据上面显示的代码,您永远不会将Fragment2添加到后堆栈中
@gabe,@Pierre,您在侦听器中使用addToBackStack()
获得非法状态异常的原因在API中有说明
在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) {
}
}
public静态类CustomTabListener实现了TabListener{
片段;
公共CustomTableListener(片段){
this.fragment=片段;
}
已选择的公共事务(选项卡,碎片事务ft){
FragmentManager fm=getFragmentManager();
FragmentTransaction newFragTrans=fm.beginTransaction();
newFragTrans.replace(android.R.id.content,fragment);
newFragTrans.addToBackStack(空);
newFragTrans.commit()
}
已选择公共空页(选项卡,碎片事务ft){
ft.去除(碎片);
}
已重新选择公共无效页签(页签,碎片事务){
}
}
我只是选了,但你明白了。另外,不要忘记提交此事务,因为侦听器只会自动提交提供的FragmentTransaction ft
最后一件事,确保在执行事务后调用addToBackStack()
,因为这是要添加到堆栈中的内容,而不是实际的片段。在上面的代码中,这不是为Fragment1的按钮单击而做的
希望这有帮助。@Pierre Rymiortz,我刚刚解决了这个问题。请参考下面的代码
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();
}
}
}
公共类StartActivity扩展SherlockFragmentActivity实现
TabListener,onbackbackchangedlistener{
私有上下文mContext=null;
私人行动吧;
私人标签mTab;
私有片段;
私有最终静态整数=0;
私有最终静态int 2=1;
私有最终静态int三=2;
私人决赛静态整数玩家=3;
private MenuItem mPlayerItem=null;
私有FragmentTransaction MFFragmentTransaction=null;
/**
*默认情况下为false-制表符在开始时为true-whe
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();
}
}
}