2013-02-14 111 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() 
    } 

它應該工作