2014-02-26 266 views
1

我目前有一個Android應用程序,在導航區域中有幾個選項卡(確切地說是3個)。點擊每個標籤顯示與該標籤關聯的片段。Android ActionBar.Tab,碎片,子片段

我希望能夠點擊正在顯示並顯示一個新片段的按鈕,該片段不是任何選項卡的一部分。基本上,它就像前一頁的子屏幕。

我能夠得到「子片段」來顯示,點擊後退按鈕將帶我到我想要的前一個片段。

我的問題是,當我點擊另一個選項卡時,「子片段」不會消失。如果我點擊後退按鈕,我會得到一個IllegalStateException,說已經添加了Fragment1。

下面是一些希望能幫助回答我的問題的代碼。

MainActivity:

public void OnTabSelected(ActionBar.Tab tab, FragmentTransaction ft) 
    { 
     string tabTag = tab.Tag.ToString(); 

     Fragment f = FragmentManager.FindFragmentByTag(tabTag); 

     if (f != null) 
     { 
      ft.Show(f); 
     } 
     else 
     { 
      switch (tabTag) 
      { 
       case "Tab1": 
        f = new Fragment1(); 
        break; 
       case "Tab2": 
        f = new Fragment2(); 
        break; 
       case "Tab3": 
        f = new Fragment3(); 
        break; 
       default: 
        f = new NotImplementedTabFragment(); 
        break; 
      } 

      ft.Add(Resource.Id.fragmentContainer, f, tabTag); 
     } 
    } 

    public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) 
    { 
     string tabTag = tab.Tag.ToString(); 

     Fragment f = FragmentManager.FindFragmentByTag(tabTag); 

     if (f != null) 
     { 
      ft.Hide(f); 
     } 
    } 

片段1:

public class Fragment1 : Fragment 
{ 

    public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Bundle savedInstanceState) 
    { 
     base.OnCreateView(inflater, container, savedInstanceState); 

     var view = inflater.Inflate(Resource.Layout.Fragment1, container, false); 
     return view; 
    } 

    protected void OnButtonClick(object sender, Android.Widget.AdapterView.ItemClickEventArgs e) 
    { 
     var t = items[e.Position].ToString(); 
     FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction(); 
     fragmentTransaction.Replace(Resource.Id.fragmentContainer, new SubFragment()); 
     fragmentTransaction.AddToBackStack(null); 
     fragmentTransaction.Commit(); 
    } 
} 

這是寫在Xamarin(C#),但我不明白的Java代碼,所以任何幫助/使用Java例子是罰款。

更新:

我意識到我MainActivityLayout.axml文件使用的FrameLayout的RelativeLayout的替代,這就是爲什麼我不得不使用安裝/拆卸,而不是顯示/隱藏。這是我的新佈局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <FrameLayout 
     android:id="@+id/fragmentContainer" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 
</LinearLayout> 

它仍然無法按預期工作,但我不明白的例外了說的片段已添加。

更新2:

我已經決定放棄試圖使用OnTabSelected和OnTabUnselected,只是因爲我使用C#中使用委託。重要的代碼是這樣的:

private void AddTab(Tab tab, Fragment fragment) 
{ 
    Android.App.ActionBar.Tab droidTab = this.ActionBar.NewTab(); 
    droidTab.SetCustomView(new TabLayout(this)); 
    droidTab.SetTag(tab.ToString()); 

    droidTab.TabSelected += delegate(object sender, ActionBar.TabEventArgs e) 
    { 
     e.FragmentTransaction.Replace(Resource.Id.fragmentContainer, fragment); 
    }; 

    this.ActionBar.AddTab(droidTab); 
} 

回答

0

我想你需要做的是保存一個參考小碎片

Fragment subFrag; 
protected void OnButtonClick(object sender, Android.Widget.AdapterView.ItemClickEventArgs e) 
{ 
    var t = items[e.Position].ToString(); 
    FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction(); 
    subFrag = new SubFragment(); 
    fragmentTransaction.Replace(Resource.Id.fragmentContainer, subFrag); 
    fragmentTransaction.AddToBackStack(null); 
    fragmentTransaction.Commit(); 
} 

然後,當片段1是detatched,除去subFrag

@Override public void onDetach() { 
    if (subFrag != null) { 
     FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction(); 
     fragmentTransaction.Remove(subFrag); 
     fragmentTransaction.Commit(); 
    } 
    super.onDetach(); 
} 

另一個(儘管在我看來有點粗糙)選項可能是在Fragment1中實施getSubFragment()方法,並執行:

public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) 
{ 
    string tabTag = tab.Tag.ToString(); 

    Fragment f = FragmentManager.FindFragmentByTag(tabTag); 

    if (f instanceof Fragment1) { 
     Fragment subFrag = ((Fragment1)f).getSubFragment(); 
     if (subFrag != null) { 
      ft.Remove(f); 
     } 
    } 
    if (f != null) 
    { 
     ft.Hide(f); 
    } 
} 
+0

我已經實現了你所說的做,但onDetach永遠不會被調用。 據Dianne Hackborn在https://groups.google.com/forum/#!topic/android-platform/QlkLMsncDwg - 「不,它有點不幸命名,onDetach()意味着從活動中分離出來。仍然附着在活動上,FragmentManager.detach()基本上把它放到與在棧上壓入時相同的狀態。「 –

+0

您是否嘗試將其移動到生命週期的另一部分,例如onDestroyView或onPause? – cYrixmorten

+0

查看我的更新。我使用RelativeLayout而不是FrameLayout來存儲片段。代碼不工作我真的很想要它,它不會讓SubFragment在單擊其他選項卡時消失,但其他片段的內容顯示出來。有點像分層效果。 –