2013-02-11 37 views
70

活動:的Android - 片段.replace()不替換內容 - 把它放在頂部

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 

Fragment1 fragment = new Fragment1(); 
Fragment2 fragment2 = new Fragment2(); 

transaction.replace(R.id.Fragment1, fragment); 
transaction.addToBackStack(null); 
transaction.commit(); 

FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction(); 
transaction2.replace(R.id.Fragment1, fragment2); 
transaction2.addToBackStack(null); 
transaction2.commit(); 

代碼在視圖中:

<fragment 
    android:id="@+id/Fragment1" 
    android:name="com.landa.fragment.Fragment1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/include1" /> 

的問題是,內容不真的被取代 - 它被放在最上面(所以它重疊)。

當我點擊後,第一個片段得到正確顯示(沒有第二個),但最初都是可見的(我只希望最後一個可見)。

我在這裏錯過了什麼?

回答

106

你錯在這裏做兩件事情:

  1. 您不能替換,它是靜態放置在xml佈局文件片段。您應該在佈局中創建容器(例如FrameLayout),然後使用FragmentTransaction以編程方式添加片段。

  2. FragmentTransaction.replace期望容器的id包含片段而不是片段的id作爲第一個參數。所以你應該傳遞第一個參數作爲你添加第一個片段的容器的id。

有關更多詳細信息,請參閱this link

+13

使用'FrameLayout'作爲容器比使用'LinearLayout'好。 – 2014-02-11 13:03:57

+1

在活動中使用一個空的FrameLayout也解決了我的問題 – 2016-02-08 12:48:34

+1

它的工作原理是這樣的。但是當我開始我的應用程序並立即按下後退按鈕時,我最終處於片段爲空的狀態,而不是退出應用程序? – MasterScrat 2017-02-08 14:16:13

3

您可以更換片段之前清除堆棧中:

FragmentManager fm = getActivity().getSupportFragmentManager(); 

    for (int i = 0; i < fm.getBackStackEntryCount(); i++) { 
     fm.popBackStack(); 
    } 

    // replace your fragments 
+0

的問題是,他已經宣佈他的XML佈局文件中的片段。因此它不能在運行時被移除/替換。 – 2013-02-11 10:53:38

+0

這對我有效,試圖在不清除後臺堆棧的情況下替換一個片段似乎將最新的後臺堆棧條目留在任何其他片段的頂部。 – speedynomads 2014-01-23 21:48:57

+0

@Michal把這段代碼放在哪裏? – Roon13 2015-12-21 20:05:58

22

我也有類似的問題,但我的問題是我使用了兩個不同的片段管理器: 一個來自getSupportFragmentManager(),一個來自getFragmentManager()。如果我用SupportFragmentManager添加了一個片段,然後嘗試用FragmentManager替換片段,那麼該片段就會被添加到頂端。我需要更改代碼,以便使用相同的FragmentManager並處理該問題。

0

我同意Sapan Diwakar的回答。但我已經找到了解決方法。

首先,在您的活動(例如activity_main)中,您擁有所有佈局,請添加FrameLayout。它的高度和寬度應該是match parent。另外,給它一個id

現在,在您要替換當前佈局的片段中,請撥打onPause()onResume()。初始化View中的所有內部容器。並設置其visibilityGONEonResume()VISIBLEonPause()

注意:不是FrameLayout你正在用這個片段替換。

假設你有ViewPagerTabLayoutImageViewactivity_main.xml定製<fragment>。如上所述添加一個FrameLayout

abcFragment.java,在onClick()函數中,添加addToBackstack(null)transaction

示例代碼:

在xyzFragment

,它將會取代abcFragment(和activity_main.xml中顯示的所有內容),這樣做

@Override 
    public void onResume() { 
     super.onResume(); 

    // On resume, make everything in activity_main invisible except this fragment. 
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs); 
    viewPager = getActivity().findViewById(R.id.pager); 
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager); 

    slidingTabs.setVisibility(View.GONE); 
    viewPager.setVisibility(View.GONE); 
    miniPlayerFragment.setVisibility(View.GONE); 
} 

@Override 
public void onPause() { 
    super.onPause(); 

    // Make everything visible again 
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs); 
    viewPager = getActivity().findViewById(R.id.pager); 
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager); 

    slidingTabs.setVisibility(View.VISIBLE); 
    viewPager.setVisibility(View.VISIBLE); 
    miniPlayerFragment.setVisibility(View.VISIBLE); 
} 

編碼愉快!

0

謝謝Sapan Diwakar等人。這個答案幫了我。我只是創建了一個沒有內部片段的RelativeLayout,使用RelativeLayout作爲父視圖或組視圖,在事務中指定該組視圖進行替換,並且它工作正常。代碼: getSupportFragmentManager()。beginTransaction() .replace(R.id.content_group_view,itemDetailFragment).commit();

佈局:

<RelativeLayout 
     android:id="@+id/content_group_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
</RelativeLayout> 
0

在MainActivity

if(condition) 
    getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();      
else 
    getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit(); 

使用的容器,而不是使用片段

<FrameLayout 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:text="Hello World!" /> 

現在請注意,您的片段類應該導入「android.app。片段' 請確保您使用「support.v4」或「原始「實現,不要混合它們。我遇到了這個問題,因爲我混合了它們。

0

您可以使用FragmentTransaction中的setTransition方法來修復重疊問題。

transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
2

我有同樣的問題,看到了所有的答案,但沒有一個包含我的錯誤! 之前試圖取代當前片段,我表示箱體活動像這樣的XML默認的片段:)

<FrameLayout 
    android:id="@+id/fragment_frame_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <fragment 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:name="....ShopFragment" 
     android:id="@+id/fragment" 
     tools:layout="@layout/fragment_shop" /> 
</FrameLayout> 

後,雖然我經過的FrameLayout到fragmentTransaction.replace(但我有確切的問題。 它顯示了上一個片段的第二個片段。

通過除去從XML片段,並將其顯示以編程在容器活動的用於在程序的這樣開始時的默認預覽onCreate()方法固定的問題:

fragmentTransaction = getFragmentManager().beginTransaction(); 
    fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment()); 
    fragmentTransaction.addToBackStack(null); 
    fragmentTransaction.commit(); 

和容器活動的xml:

<FrameLayout 
    android:id="@+id/fragment_frame_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
+0

同樣在這裏。謝謝!!!! – cesards 2017-04-21 10:41:39

0

在OnCreate中()

BaseFragmentloginpage fragment = new BaseFragmentloginpage(); 
      android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
      fragmentTransaction.replace(R.id.frame, fragment); 
      fragmentTransaction.isAddToBackStackAllowed(); 
      fragmentTransaction.commit(); 

現在這將是永遠的默認片段......如果你在XML佈局添加片段,它會永遠重疊,所以請爲片段初始內容在運行時

0

我使用這個問題後,有同樣的問題,解決

其中u更換烏爾片段

<FrameLayout 
       android:id="@+id/fragment_place" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 
  • 和代碼替換

    1. 採取幀佈局

      public void selectFrag(View view) { 
      Fragment fr; 
      
          if(view == findViewById(R.id.button2)) 
      { 
          fr = new FragmentTwo(); 
      
      }else { 
          fr = new FragmentOne(); 
      } 
      FragmentManager fm = getFragmentManager(); 
      FragmentTransaction fragmentTransaction = fm.beginTransaction(); 
      fragmentTransaction.replace(R.id.fragment_place, fr); 
      fragmentTransaction.commit(); 
      

    如果你想整例如我會送你剛纔評論我......