我有一个活动和许多片段在同一个FrameLayout
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
示例:mainActivity&gt;任何片段(按下后退按钮)&gt;活动是空白的。
on onCreate:
layout = (FrameLayout)findViewById(R.id.content_frame);
layout.setVisibility(View.GONE);
当我开始片段时:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
ft.addToBackStack(null);
ft.commit();
layout.setVisibility(View.VISIBLE);
我想我需要在后退时再次进行frameLayout的可见性GONE
,但我该怎么做?
我尝试了onBackPressed
并设置了layout.setVisibility(View.GONE);
但我无法通过片段返回,因为我直接转到主页。
答案 0 :(得分:112)
如果您在活动中使用了多个片段,或者即使您只有一个片段,那么第一个片段也不应该定义addToBackStack。由于这允许返回导航,因此在此片段之前将显示空活动布局。
// fragmentTransaction.addToBackStack() // dont include this for your first fragment.
但是对于另一个片段,你需要定义它,否则后面将不会导航到早期的屏幕(片段),而是应用程序可能会关闭。
答案 1 :(得分:39)
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else {
int fragments = getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
finish();
} else if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
添加片段
getSupportFragmentManager().beginTransaction()
.replace(R.id.layout_main, dashboardFragment, getString(R.string.title_dashboard))
.addToBackStack(getString(R.string.title_dashboard))
.commit();
答案 2 :(得分:22)
对于迟到的回复感到抱歉。
添加第一个片段时,您不必添加 ft.addToBackStack(null); 。
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
// ft.addToBackStack(null); --remove this line.
ft.commit();
// ... rest of code
答案 3 :(得分:17)
如果您想按片段进行追踪,则应覆盖onBackPressed
方法,例如
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
}
答案 4 :(得分:14)
您可以覆盖onBackPressed
并检查Backstack上是否有任何内容。
@Override
public void onBackPressed() {
int fragments = getFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
// make layout invisible since last fragment will be removed
}
super.onBackPressed();
}
答案 5 :(得分:2)
在最近的个人项目中,如果堆栈为空,我通过不调用addToBackStack
解决了这个问题。
// don't add the first fragment to the backstack
// otherwise, pressing back on that fragment will result in a blank screen
if (fragmentManager.getFragments() != null) {
transaction.addToBackStack(tag);
}
这是我的全面实施:
String tag = String.valueOf(mCurrentSectionId);
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
// if the fragment exists then no need to create it, just pop back to it so
// that repeatedly toggling between fragments doesn't create a giant stack
fragmentManager.popBackStackImmediate(tag, 0);
} else {
// at this point, popping back to that fragment didn't happen
// So create a new one and then show it
fragment = createFragmentForSection(mCurrentSectionId);
FragmentTransaction transaction = fragmentManager.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.main_content, fragment, tag);
// don't add the first fragment to the backstack
// otherwise, pressing back on that fragment will result in a blank screen
if (fragmentManager.getFragments() != null) {
transaction.addToBackStack(tag);
}
transaction.commit();
}
答案 6 :(得分:2)
只需不将第一个片段添加到堆栈中
这是对我有用的Kotlin代码。
val ft = supportFragmentManager.beginTransaction().replace(container, frag)
if (!supportFragmentManager.fragments.isEmpty()) ft.addToBackStack(null)
ft.commit()
答案 7 :(得分:1)
我仍然无法通过getBackStackEntryCount()
解决问题,我也通过将主页面设为片段来解决我的问题,所以最后我的活动只有FrameLayout
;和所有其他片段,包括主页面,我膨胀到该布局。这解决了我的问题。
答案 8 :(得分:1)
如果您想在第一个片段上按下后退按钮时结束活动,则irscomp的解决方案有效。但是如果你想跟踪所有片段,并按照后面的顺序从一个片段返回到另一个片段,则将所有片段添加到堆栈中:
ft.addToBackStack(null);
然后,将其添加到onCreate()的末尾以避免在最后一次按下时出现空白屏幕;您可以使用getSupportFragmentManager()或getFragmentManager(),具体取决于您的API:
FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0) finish();
}
});
最后的话:我不建议你使用这个解决方案,因为如果你从fragment1转到片段2,反之亦然10次,当你按回10次按钮时,它会按顺序执行,用户不会想要它。
答案 9 :(得分:1)
与 Goodlife 的答案几乎相同,但是以Xamarin.Android
的方式:
加载片段(我为此编写了帮助方法,但它没有必要):
public void LoadFragment(Activity activity, Fragment fragment, string fragmentTitle = "")
{
var fragmentManager = activity.FragmentManager;
var fragmentTransaction = fragmentManager.BeginTransaction();
fragmentTransaction.Replace(Resource.Id.mainContainer, fragment);
fragmentTransaction.AddToBackStack(fragmentTitle);
fragmentTransaction.Commit();
}
后退按钮(MainActivity
中的):
public override void OnBackPressed()
{
if (isNavDrawerOpen()) drawerLayout.CloseDrawers();
else
{
var backStackEntryCount = FragmentManager.BackStackEntryCount;
if (backStackEntryCount == 1) Finish();
else if (backStackEntryCount > 1) FragmentManager.PopBackStack();
else base.OnBackPressed();
}
}
isNavDrawerOpen
方法:
bool isNavDrawerOpen()
{
return drawerLayout != null && drawerLayout.IsDrawerOpen(Android.Support.V4.View.GravityCompat.Start);
}
答案 10 :(得分:1)
在处理Firebase的Ui登录屏幕时,我遇到了同样的问题。按下“后退”按钮时,它会留下一个空白屏幕。
要解决该问题,我刚刚在finish()
方法中为“活动”调用了onStop()
。像魅力一样工作。