我目前正在使用一个ActionBarActivity
和更多Fragments
构建Android应用程序(14< = SDK< = 21),例如ListFragment
和{{1} },在单个MapFragment
视图中交换。
ActionBarActivity自动替换/提交片段A.然后,当用户点击一个按钮时,托管活动替换/提交一个新的不同片段B.我的目标是让用户在按下后立即返回片段A.后退按钮。
现在有些代码。
MainActivity
FrameLayout
的问题
即使调用public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
StopItemFragment.OnFragmentInteractionListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
fragmentManager.enableDebugLogging(true);
...
if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, list)
.addToBackStack(null)
.commit();
}
...
@Override
public void onFragmentInteraction(String id) {
selectItem(Integer.parseInt(id));
}
private void selectItem(int position) {
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
...
}
}
,当我在片段B上时,我也无法返回片段A. MainActivity直接关闭。
然而,我试图自己管理背堆,没有运气。我可以看到片段在堆栈上但是如果我调用addToBackStack()
,则弹出片段A并且不执行片段事务。 (先回来什么都没发生,第二次活动关闭)
我还附加了FragmentManager logcat:
http://pastebin.com/hFLHprL8
答案 0 :(得分:71)
对于那些仍在寻找解决方案的人。
在主Activity
类(托管片段)中,只需覆盖onBackPressed()
。
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
片段中没有onBackPressed()
方法,此方法仅适用于activity
。因此,当我们按后退键时,会显示activity
的默认行为,即
您将转到之前的活动(如果有)或应用程序 将退出。
现在我们需要覆盖这个方法来告诉activity
当我们按下后退键时,如果后面的堆栈中有任何片段,则将它们弹出(这是addToBackStack()
到来的时候进入图片)。否则,请遵循默认行为。
答案 1 :(得分:5)
试试这个(注意添加而非替换表示fragmentA, addToBackStack()表示fragmentB)
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.add(R.id.content_frame, list)
.commit();
和
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("FragmentB")
.commit();
答案 2 :(得分:5)
我必须手动拨打beginTransaction()
的{{1}}和commit()
通过覆盖FragmentManager
解决:
onBackPressed()
答案 3 :(得分:1)
如果你正在与addToBackStack()& popBackStack()然后只需使用
FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`
在你的活动中OnBackPressed()通过标签找出fargment然后做你的东西
Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
if (home instanceof HomeFragment && home.isVisible()) {
// do you stuff
}
更多信息https://github.com/DattaHujare/NavigationDrawer 我从不使用addToBackStack()来处理片段。
答案 4 :(得分:0)
popBackStack()
和popBackStackImmediatly()
的原因是你没有将该片段(你要弹出)添加到backStack。为此,您必须在使事务添加/替换片段时调用addToBackStack()。
答案 5 :(得分:0)
首先,我想对突出显示的[Nick]的回答表示感谢(低声望不能在下面发表评论),因为它帮助我知道确实存在一些未提及的问题。 Android文档。
第二,现在是2019年,在Androidx的“偏好设置”中尝试了类似的方式后,我很长一段时间都找不到任何东西,直到我同时检查了这个问题和一个official sample code in Kotlin,这个问题导致一个线索,示例代码的方式实际上就是我的解决方案,就像一个魅力,只有很小的覆盖,希望它对那些正在寻找正式解决方案的人也有帮助
@Override
public boolean onSupportNavigateUp() {
if (getSupportFragmentManager().popBackStackImmediate()){
return true;
}
return super.onSupportNavigateUp();
}
Aforementioned code in Java (Screenshot)
P.S。在使用至少5年以上之后,我对stacksoverflow的第一个回答^^