活动是空白的

我有一个活动和许多片段在相同的 FrameLayout膨胀

<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />

例如: mainActivity > any 嘛片段(按后退按钮) > activity 是空白的。

在 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);

我想我需要使框架布局的可见性 GONE再次背压,但我如何做到这一点?


我尝试了 onBackPressed和设置 layout.setVisibility(View.GONE);,但我不能回去通过片段,因为我直接去主页。

83125 次浏览

您可以覆盖 onBackPressed并检查是否有任何在回栈上。

@Override
public void onBackPressed() {
int fragments = getFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
// make layout invisible since last fragment will be removed
}
super.onBackPressed();
}

我仍然不能通过 getBackStackEntryCount()解决这个问题,我也通过使主页成为片段来解决我的问题,所以最后我只有一个 FrameLayout的活动; 所有其他片段,包括我放大到那个布局的主页。这解决了我的问题。

抱歉这么晚才回复。

在添加第一个片段时不必添加 AddToBackStack (空) ;

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, profileFragment);
// ft.addToBackStack(null); --remove this line.
ft.commit();
// ... rest of code

如果您希望在第一个片段上按下后退按钮时结束活动,则 irscomp 的解决方案可以工作。但是,如果您想跟踪所有的片段,并按照顺序从一个片段返回到另一个片段,则需要将所有片段添加到堆栈中:

ft.addToBackStack(null);

然后,将其添加到 onCreate ()的末尾,以避免在最后一次按下时出现空白屏幕; 您可以使用 getSupportFragmentManager ()或 getFragmentManager () ,具体取决于您的 API:

FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() == 0) finish();
}
});

最后一句话: 我不建议你使用这个解决方案,因为如果你从片段1到片段2,反之亦然10次,当你按回退按钮10次时,它将按用户不想要的回退顺序来做。

在最近的一个个人项目中,如果堆栈为空,我就不调用 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();
}

如果活动中使用了多个片段,或者即使只有一个片段,那么第一个片段也不应该定义 addToBackStack。因为这允许向后导航,在这个片段之前,将显示空的活动布局。

 // fragmentTransaction.addToBackStack() // dont include this for your first fragment.

但是对于其他片段,您需要定义这个,否则后面将不会导航到早期的屏幕(片段) ,而是应用程序可能会关闭。

如果要通过片段进行跟踪,则应重写 onBackPressed方法,如下所示

public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
}
@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();

几乎与 好日子的答案相同,但是以 Xamarin.Android的方式:

负载片段(我为此编写了 helper 方法,但没有必要) :

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);
}

只是不要把第一个片段放回堆栈

这是我用过的科特林密码。

    val ft = supportFragmentManager.beginTransaction().replace(container, frag)
if (!supportFragmentManager.fragments.isEmpty()) ft.addToBackStack(null)
ft.commit()

我在处理 Firebase 的 Ui 登录界面时也遇到了同样的问题。当后退按钮被按下时,它留下了一个空白屏幕。

为了解决这个问题,我在我的 onStop()方法中调用了 finish()来处理这个 Activity。

如果您遇到像我这样的场景,一个列表片段打开另一个详细信息片段,在后面按下时,您首先需要显示列表片段,然后取出整个活动,addToBackStack用于所有的片段事务。 然后在活动上,这样做(礼貌:@JRomero 的回答,@MSaudi 的评论)

@Override
public void onBackPressed() {
int fragments = getFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
// make layout invisible since last fragment will be removed
}
super.onBackPressed();
}

只需在代码中注释或删除 transaction.addToBackStack (null)。

fun ChangeFragment(activity: MainActivity, fragment: Fragment) {


val transaction: FragmentTransaction =
activity.getSupportFragmentManager().beginTransaction()
transaction.replace(R.id.tabLayoutContainer, fragment)
transaction.commit()
}