2013-02-14 112 views
2

我在一个FragmentActivity内使用一个FragmentTabHost,它有3个选项卡。 如果我改变从每个选项卡的第一页选项卡它的工作正常,但如果我导航抛出片段内一个选项卡,然后更改选项卡,它显示新的片段重叠到旧的。 有人可以帮助我吗?FragmentTabHost显示片段重叠

这是FragmentActivity(fragments_tab.xml)的布局:

<?xml version="1.0" encoding="UTF-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/relativeLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:src="@drawable/background_gradient"> 

    <ImageView 
     android:contentDescription="@string/app_name" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:src="@drawable/background_gradient" /> 

    <android.support.v4.app.FragmentTabHost 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/tabhost" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

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

     <TabWidget 
      android:id="@android:id/tabs" 
      android:orientation="horizontal" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="0"/> 

     <FrameLayout 
      android:id="@android:id/tabcontent" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_weight="0"/> 

     <LinearLayout 
      android:id="@+id/realtabcontent" 
      android:layout_width="match_parent" 
      android:layout_height="0dp" 
      android:layout_weight="1"/> 

    </LinearLayout> 
    </android.support.v4.app.FragmentTabHost> 
    </RelativeLayout> 

我FragmentActivity代码:

public class MainActivity extends FragmentActivity { 

     private FragmentTabHost mTabHost; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setDB(); 
      setContentView(R.layout.fragments_tab); 

      mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 

      mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 


      mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home",  getResources().getDrawable(R.drawable.ic_menu_home)), 
        HomeFragment.class, null); 

      mTabHost.addTab(mTabHost.newTabSpec("Map").setIndicator("Map", getResources().getDrawable(R.drawable.ic_menu_mapmode)), 
        MapMenuFragment.class, null); 
      mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.ic_menu_info_details)), 
        InfoFragment.class, null); 
     } 
} 

每个片段创建这样:

public class InfoFragment extends Fragment { 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) 
    { 
     super.onActivityCreated(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     View view = inflater.inflate(R.layout.fragment_info, container, false); 
     return view; 
    } 

有人能够帮助我好吗?

回答

0

我其实也有类似的问题。我选择ListFragment中的项目,然后创建一个新的片段,并替换标签布局中的原始列表片段。我发现,当我切换到其他选项卡时,我会遇到多个片段同时显示的问题,彼此重叠,或者我会看到应该显示消失的片段。我的解决办法是清除后退堆栈时选择一个新的选项卡,请尝试在TabListener

FragmentManager manager = getSupportFragmentManager(); 

    if(manager.getBackStackEntryCount() > 0) 
    { 
     manager.popBackStack(null, 
          FragmentManager.POP_BACK_STACK_INCLUSIVE); 
    } 

这样做解决了问题,我将此代码添加到您的onTabSelected()方法。

+0

谢谢回复@WingedRayeth,但我认为您的解决方案,你会每次你改变标签的时间清理堆栈。因此,例如,如果您导航到第一个选项卡直到第四个片段,然后更改选项卡,那么当您返回到第一个选项卡时,您将从第一个片段重新启动。 我终于找到解决办法,我会在下面解释 – al1812 2013-03-02 10:24:45

1

我找到了解决我的问题。 在我的项目中,每个片段都是扩展类Fragment的不同类。当FragmentTabHost试图分离旧片段时,它无法找到Fragment对象,因此它不会删除任何内容。

我不是那么专业,我相信有一个更简单的方法,但经过很多很多头痛,我发现这个解决方案的工作。 这是我做过什么:

  • 我保存的当前片段为每个标签为对象变量的活动。
  • 我将FragmentTabHost的代码复制到自己的类中,并在调用detach或attach时更改了方法doTabChanged。

(我有3个选项卡 “主页”, “地图” 和 “信息”)

分离:

//ft.detach(mLastTab.fragment); 
if(mLastTab.tag == "Home") ft.detach((Fragment) tabHomeFragment); 
else if(mLastTab.tag == "Info") ft.detach((Fragment) tabInfoFragment); 
else ft.detach((Fragment) tabMapFragment); 

附:

//ft.attach(newTab.fragment); 
if(newTab.tag == "Home") ft.attach((Fragment) tabHomeFragment); 
else if(newTab.tag == "Info") ft.attach((Fragment) tabInfoFragment); 
else ft.attach((Fragment) tabMapFragment); 

tabHomeFragment,tabMapFragment和tabInfoFragment包含每个标签的当前片段

0

Th发生问题是因为TabHost无法正确管理您添加的片段。

我曾遇到同样的问题,并通过Fragment Container模式解决。

FragmentContainer是一个自定义的类,从片段扩展而来。您可以使用容器初始化每个选项卡。

每个容器通过getChildFragmentManager()来管理他们自己的子片段。 你可以添加,替换,删除任何你想要的东西。

当Tab改变时,容器也被切换,没有重叠问题。

下面是一个简单的容器我所创作的: https://stackoverflow.com/a/15903349/1695108

0

我也遇到过类似的情况,我下面的工作。

检查savedInstanceState是否为空,在这种情况下,不执行片段事务。它将解决这个问题。

if (homeFragment == null) { 
    if (savedStateInstance != null) { 
    homeFragment = (HomeFragment) fragmentManager.findFragmentByTag(HOME_FRAGMENT); 
    return; 
} 
// tie new fragment 
homeFragment = new HomeFragment(); 
homeFragment.setArguments(bundle); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.add(homeFragment, HOME_FRAGMENT); 
transaction.commit(); 
} 

希望这有助于。

1

我知道这是一个相当古老的问题,但我会提供我的解决方案,所以任何人都可以阅读此问题。 我有同样的问题,我意识到,这个问题是通过调用

mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

,因为在进行此调用时,tabhost将inizialize这个FrameLayout里与mTabHost.addTab方法

我解决了指定的所有片段引起了我问题以这种方式调用

mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent); 

中,FrameLayout里R.id.tabcontent将被隐藏(宽度= 0,高= 0),而且比,简单地实现OnTabChangeListener,你可以做到这一点

@Override 
    public void onTabChanged(String tabId) { 
     FragmentTransaction t = getSupportFragmentManager().beginTransaction(); 
     if (tabId.equals(Frament1.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment1.newInstance()); 
     } else if (tabId.equals(Frament2.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment2.newInstance()); 
     } else if (tabId.equals(Frament3.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment3.newInstance()); 
     } 
     //optional 
     t.addTobackStack(); 

     t.commit() 
    } 

它应该工作