Android:片段重叠问题

时间:2013-08-16 13:40:32

标签: android android-fragments overlapping

当我在标签之间切换并将片段附加到标签视图时,我遇到了重叠片段的问题 下面是我的代码请帮助

public class FragmentManage extends Fragment implements ActionBar.TabListener {

    private Fragment mFragment;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
            Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_manage, container, false);

        OnClickListener clickListener = new OnClickListener() { 
            public void onClick(View v) {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                switch(v.getId()) {
                    case R.id.imageBtnCategory:
                        if (mFragment == null){
                            mFragment = new FragmentCategory();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                    case R.id.imageBtnManageKey:
                        if (mFragment == null){
                            mFragment = new FragmentKeys();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                    case R.id.imageBtnChangePswd:
                        if (mFragment == null){
                            mFragment = new FragmentChangePwd();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                }
                ft.commit();
             }
        };

        ImageButton imageBtnCategory = (ImageButton) v.findViewById(R.id.imageBtnCategory);
        ImageButton imageBtnManageKey = (ImageButton) v.findViewById(R.id.imageBtnManageKey);
        ImageButton imageBtnChangePswd = (ImageButton) v.findViewById(R.id.imageBtnChangePswd);

        imageBtnCategory.setOnClickListener(clickListener);
        imageBtnManageKey.setOnClickListener(clickListener);
        imageBtnChangePswd.setOnClickListener(clickListener);

        return v;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mFragment = new FragmentManage();
        ft.add(android.R.id.content, mFragment);
        ft.attach(mFragment);
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(mFragment);
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {

    }
}

17 个答案:

答案 0 :(得分:81)

只需在XML文件中为<fragment />设置背景颜色。

解决问题。

答案 1 :(得分:15)

我可能很晚才回答这个问题。

注意:

这个答案可能与上述问题无关,但希望对某些人有所帮助。

有时,当我们尝试使用不同类型的片段时会发生片段重叠问题(即在少数片段中使用支持片段,在其他片段中使用正常片段)

最近我在导航抽屉中遇到了同样的问题。 错误地,我使用&#34; import android.support.v4.app.Fragment; &#34;在一个片段中,使用&#34; 导入android.app.Fragment; &#34;在其他一些片段中。

希望这会对某人有所帮助..

答案 2 :(得分:10)

片段管理器维护所有先前片段的堆栈,有时后面的堆栈片段与我们替换的片段重叠,对我来说

  fragmentManager.popBackStack(); 

工作,我们也可以循环执行此操作以弹出堆栈中的所有片段,希望它有所帮助,谢谢。快乐编码:)

答案 3 :(得分:10)

设置片段背景颜色不是解决方案,因为片段仍然会在活动堆栈中消耗内存。

解决方案是在添加任何新片段之前从framelayout中删除所有视图。

private void changeFragment(Fragment fr){
    FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
    fl.removeAllViews();
    FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction();
    transaction1.add(R.id.mainframe, fr);
    transaction1.commit();
}

答案 4 :(得分:4)

这是我修复它的方式..

仅当布局与填充屏幕匹配时,设置背景才会从屏幕中删除重叠效果

按钮点击上替换的新片段未在tab_selected或制表符更改操作

上被替换

以下代码为我修复了

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    // This is required since button click replaces fragment whose link is lost hence overlapping isuee was occuring
    ft.replace(android.R.id.content, mFragment); 
    // On Tab Change remove old fragment views
    ft.remove(mFragment);
}

答案 5 :(得分:4)

另一个问题可能与使用android.R.id.content作为容器有关。我刚刚创建了FrameLayout并从那里使用了id。

答案 6 :(得分:3)

我也面临片段重叠的问题。这就是我解决它的方法 -

1)我们需要使用addToBackStack添加第一个片段,以便它保留在堆栈中 -

FirstFragment firstFragment = new FirstFragment();
getFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).addToBackStack("first frag").commit();

2)在添加第二个片段时,替换第一个片段而不是添加它。因为第一个片段已经添加到堆栈中,所以当你从第二个片段按回来时它会出现 -

SecondFragment secondFragment= new SecondFragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack("second frag").commit();

3)以下是如何处理背压,下面的代码应该存在于父活动 -

 public void onBackPressed(){
    if(getFragmentManager().getBackStackEntryCount() <= 1){
       super.onBackPressed();
    } else {
       getFragmentManager().popBackStack();
    }
 }

答案 7 :(得分:2)

您是否检查XML并查看主布局是否为“框架布局”?如果不是,请改用“框架布局”。这将解决重叠的问题。那是修复的唯一方法。我在寻找此问题的解决方案时尝试了“已接受”的答案,但没有成功。

答案 8 :(得分:1)

private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 =getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();}

答案 9 :(得分:0)

使用FragmentContainerView,而不是将片段用作片段的容器。为我解决了这个问题

答案 10 :(得分:0)

我找到了简单而干净的解决方案。对我来说,问题是在我的Activity的onCreate()的每次调用中执行片段事务。 现在我只在savedInstanceState == null

时执行事务
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
        // replace fragment 
        }
    }

答案 11 :(得分:0)

我不认为实现白色背景是一种安全的解决方案,尽管它可能很方便。基本上问题出现是因为片段管理器对于弹出哪个片段感到困惑。

backstack看起来像这样,认为你的碎片4 1-> 2,2-> 3,3-> 4 但你实际上是因为某种原因而在Frag 6上,所以popbackstack会去

删除(4)添加(3)&lt; - 现在你有3个(新)和6个(留下)混合在一起

为了更好地控制我的导航,我会跟踪我当前/以前的片段,并像这样替换它们。这允许我的应用程序控制片段导航。

if ( !(currentFragment instanceof Settings)) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, settings);
        fragmentTransaction.addToBackStack(null);
        previousFrag = currentFragment;
        currentFragment = settings;
        fragmentTransaction.commit();
    }

其次,我相信fragmentmanager.replace()方法是一个更好的选择。不确定当时OP是否可以使用它。

第三,要处理机器人本机背压,您需要能够无限回滚。许多人建议不要使用此行将第一个片段添加到后台堆栈。

fragmentTransaction.addToBackStack(空);

但是,如果是这种情况,您必须检查是否第一次加载应用程序。如果不是,并且您排除了此行,则只要您浏览此片段,您的应用就会遇到这些问题。我宁愿把它留在原地,而是做以下事情。

不确定这是否是一个很好的解决方案,但效果非常好。

1-获得背堆计数 2-删除所有现有的frags 3-跟踪碎片对象 4-如果它是用户希望退出的堆栈中的最后一个frag,并且因为我们将主活动添加到后台堆栈,我们需要双重弹出

@Override
public void onBackPressed() {

int num = getFragmentManager().getBackStackEntryCount();


        fl.removeAllViews();
        super.onBackPressed();

        if  (currentFragment != previousFrag) {
            currentFragment = previousFrag;
        }else{
            currentFragment = null;
        }

        if (num == 1){
           super.onBackPressed();
        }

答案 12 :(得分:0)

当我遇到这样的问题时,似乎我正在使用childFragmentManager添加一个片段而另一个使用父代的fragmentManager添加片段,因此请检查您是否使用相同类型的片段管理器。

答案 13 :(得分:0)

使背景颜色为白色也解决了它。我认为这是Android片段管理器中的错误或实现问题。我正确地实现了我的replace和popBackStack()。

答案 14 :(得分:0)

这一切都与 replace addToBackStack 方法背后的工程有关。

替换方法实际上会做两件事。隐藏现有的片段(让我们说A)并在容器中添加一个新片段(让他们说B)。

将该事务添加到后台堆栈将执行相反的操作。 删除B并添加A.

所以,你的问题的解决方案是  1.使用 addToBackStack 方法  2.确保反向替换片段的顺序正确

第二个建议非常重要,因为在某些时候通常会删除当前片段并添加另一个片段,这会导致两个片段同时显示。

答案 15 :(得分:0)

我有有时相同的问题,但我的问题与不同的片段管理器无关(getSupportFragmentManager()getFragmentManager())。我认为还有另一个问题。在我的情况下,当我打开导航抽屉时,我总是删除每个菜单选项上的旧片段,例如:

Fragment calendarFragment = context.getSupportFragmentManager().findFragmentByTag(FragmentTag.CALENDAR.name());
if (calendarFragment != null)
{
    context.getSupportFragmentManager().beginTransaction().remove(calendarFragment).commit();
}

如果没有导航抽屉,就无法进入子菜单,因此基本上总是删除片段。在某些情况下,在我删除并在Activity中再次添加片段后,它会突然与另一个(上一个)片段重叠?!但为什么片段管理器突然发现以前的片段? 这可能意味着片段管理器是错误的,它不会删除旧片段,或者其他东西被破坏 我的想法是,它在某种程度上是Android Studio或其使用的任何其他adb开发工具的错误。为什么我认为这是因为Android Studio有时似乎会丢失正在运行的应用程序的实例。可能这个问题与某个问题有关:Android Studio not deploying changes to app。当这种情况发生时,我还没弄明白。我所知道的是,它不能成为一个编程问题,因为在我通过Android Studio重新启动应用程序之后,它无法重现。我猜有任何后台进程挂起导致多个活动,片段,片段管理器等实例。此外,这不仅仅是这个错误。我在过去看到了许多与此类似的奇怪行为。 (例如,当IDE未启动应用程序时,行为突然消失)。

答案 16 :(得分:0)

当你有一个重叠片段时,你的片段的背景可能是透明的,你需要在片段中放置一个android:background =“@ color / white”

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"

和白色你需要放在colors.xml里面 其余文件夹中的#FFFFFF。