Android 碎片后退。碎片即使在爆炸后也会重叠。

Android 碎片后退。碎片即使在爆炸后也会重叠。,android,android-fragments,overlapping,fragment-backstack,Android,Android Fragments,Overlapping,Fragment Backstack,问题是要正确管理后堆栈,以便弹出(或删除)上一个片段。问题在于它们的重叠 该方案的结构如下: 每个部分有3个片段的滑动菜单:CatalogFragment,NewsFragment,BlogFragment 每个片段都是一个包含项的listView(从JSON解析) 在CatalogFragment的项目上,单击我需要将此CatalogFragment替换为LessonsFragment,这也是一个列表 p、 美国商品是俄语的,但我想你能理解 这就是添加这些片段的方式(动态): 这就是我如

问题是要正确管理后堆栈,以便弹出(或删除)上一个片段。问题在于它们的重叠

该方案的结构如下:

  • 每个部分有3个片段的滑动菜单:
    CatalogFragment
    NewsFragment
    BlogFragment
  • 每个片段都是一个包含项的listView(从JSON解析)
  • CatalogFragment
    的项目上,单击我需要将此
    CatalogFragment
    替换为
    LessonsFragment
    ,这也是一个列表
p、 美国商品是俄语的,但我想你能理解

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

这就是我如何在接口中的
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();
}
…这很好:

但当我从SlidedNG菜单返回到片段时,片段重叠

我相信问题在于适当的后台管理,但我不知道我做错了什么。另一个建议是,在这种情况下,我需要更好地使用
add/replace

我已经尝试从堆栈中按名称删除。可能需要按ID删除它们

请告诉我是否需要更多的代码。
提前谢谢

尝试只传递一个空字符串作为addToBackStack中的片段标识符

而不是

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

getSupportFragmentManager().popBackStack();

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


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

</LinearLayout>
我猜这是您的片段xml,可能是其他类型的布局(相对、框架或其他),请尝试将您的父片段xml布局的背景色设置为
例如,我把白色作为背景。

我认为这不是一个完美的解决方案,但这对我来说很有效

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

所以,我在activity中按下catch back按钮,在弹出BackBackback之后,当片段与另一个片段重叠时,这个重叠片段是可见的,所以我只是将其与事务一起移除。

发生这种情况的另一个原因是:

  • 您正在将所有片段替换到id为:
    R.id.container
    的视图中

  • 假设您正在推送一个片段
    a
    ,其顶层布局具有分配给它的id,例如

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


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

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

@Chrimson Tulip未更改任何内容。我确实用新的片段替换了片段。但是当我从
课程
回到
目录
时,它们重叠了。反之亦然,当我从
目录
移动到
课程
时,它确实起作用。这一定是某种魔力:染料!谢谢你成就了我的一天:D我已经忍受了第二个晚上。这不是正确的解决方案,重叠的片段将窃取你的输入事件。因此导致了其他问题。我也遇到了同样的问题,我最终尝试弹出后堆栈,并使用
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_容器,fragmentInstance).addToBackStack(一些名称).commit()创建了一个新的片段android:clickable=“true”android:focusable=“true”
来解决这个问题。没错,谢谢。但钱德拉坎特是第一个回答问题的人,他没有测试,但很欣赏你有趣的方法。
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();
}