片段BackStack。片段即使在流行后也会重叠。

时间:2015-01-22 12:18:56

标签: android android-fragments overlapping fragment-backstack

问题是正确管理后备堆栈,以便先前(或删除)前一个片段。问题出在重叠......

程序结构如下:

  • 每个部分包含3个片段的滑动菜单:CatalogFragmentNewsFragmentBlogFragment;
  • 每个片段都是带有项目的listView(从JSON解析);
  • CatalogFragment项目点击后,我需要将此CatalogFragment替换为LessonsFragment,这也是列表。

P.S。项目是俄语,但我认为你可以理解

enter image description here

这是(动态)添加这些片段的方式:

    @Override
public void onNavigationDrawerItemSelected(int position) {
    FragmentManager fragmentManager = getSupportFragmentManager();
//        fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); //this also doesn't work

    switch (position+1) {
        case 1:
            //getSupportFragmentManager().popBackStack(); // this doesnt work
            fragmentManager.beginTransaction().replace(R.id.container,
                    CatalogFragment.newInstance(position + 1)).addToBackStack("catalog").commit();

            break;
        case 2:
            fragmentManager.beginTransaction().replace(R.id.container,
                    NewsFragment.newInstance(position + 1)).addToBackStack("news").commit();

            break;
        case 3:
            fragmentManager.beginTransaction().replace(R.id.container,
                    BlogFragment.newInstance(position + 1)).addToBackStack("blog").commit();
            break;
    }
}

我是如何在接口的onCatalogFragmentInteraction方法中用新的替换片段的方式:

    /** Methods for interaction with list items*/
@Override
public void onCatalogFragmentInteraction(String id){
    //pop previous
    getSupportFragmentManager().popBackStack("catalog", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    //add new
    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.container, LessonsFragment.newInstance());
    fragmentTransaction.addToBackStack("lessons");
    fragmentTransaction.commit();
}

......这很好用:

enter image description here

但是当我从slididng菜单片段重叠回到片段时。

enter image description here

我相信问题在于正确的BackStack管理,但我无法弄清楚我做错了什么。另一个建议是,在这种情况下,我需要以某种方式更好地使用add/replace

我已尝试从堆栈中删除名称。也许需要通过ID删除它们?

P.S。告诉我们是否需要更多代码。 提前致谢。

6 个答案:

答案 0 :(得分:14)

我认为你的所有片段都有透明的背景,或者你没有设置任何东西(所以默认是透明的)。因此,当您在另一个片段上方添加/替换片段时,您可以看到下面的片段。因此,尝试为每个片段布局设置背景颜色。

答案 1 :(得分:2)

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        android:orientation="vertical" >

</LinearLayout>

我猜这是你的xml片段,它可能是其他类型的布局(相对,帧或其他),尝试将背景颜色设置为父布局 xml片段。 例如,我为背景设置了白色。

答案 2 :(得分:2)

我认为这不是完美的解决方案,但这对我有用。

long back_pressed;
@Override
public void onBackPressed()
{
    Log.d(TAG, "HERE WAS PRESSED BACK");
    int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
    final Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_ANSWERS_FRAGMENT);
    if(null != fragment && fragment.isVisible()) {
        Log.d(TAG, "visible");
        showLeaveTest();
    }
    else {
        Log.d(TAG, "invisible");
        if (backStackEntryCount == 0) {
            if (back_pressed + 2000 > System.currentTimeMillis()) super.onBackPressed();
            else try {
                Toast.makeText(this, R.string.double_press, Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
            back_pressed = System.currentTimeMillis();
        } else {
            getSupportFragmentManager().popBackStack();
            removeCurrentFragment(TAG_RESULT_FRAGMENT);
        }
    }
}

public void removeCurrentFragment(String fragmentTag)
{
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    Fragment currentFrag =  getSupportFragmentManager().findFragmentByTag(fragmentTag);
    String fragName = "NONE";

    if (currentFrag != null)
        fragName = currentFrag.getClass().getSimpleName();

    Log.d(TAG, "flag name " + fragName);

    if (currentFrag != null && currentFrag.isVisible())
        transaction.remove(currentFrag);

    transaction.commit();
}

所以,我在活动中按回按钮,并且在弹出backstack之后,当片段与另一个片段重叠时,这个重叠的片段是可见的,所以我只是用事务删除它。

答案 3 :(得分:1)

尝试在addToBackStack中仅传递一个空字符串作为片段标识符。

而不是

getSupportFragmentManager().popBackStack("catalog", FragmentManager.POP_BACK_STACK_INCLUSIVE

只需使用

getSupportFragmentManager().popBackStack();

答案 4 :(得分:0)

还有另一个原因可能发生这种情况:

  • 您正在将所有片段替换为ID为R.id.container的视图。

  • 假设您正在推送片段A,其顶层布局已为其分配了ID,例如<LinearLayout android:id="@+id/rootLayout">

  • 现在,您推送到R.id.container的任何其他片段都会与片段A重叠。

因此,只需确保正在推送的片段的根布局没有分配id。

答案 5 :(得分:0)

只需为每个片段的父布局设置背景颜色