I currently have an Android app which has a few tabs (3 to be exact) in a navigation area. Clicking on each tab shows the fragment associated with the tab.
I want to be able to click on a button in the fragment that is showing and display a new fragment, which isn't part of any of the tabs. Basically, it's like a sub-screen for the previous page.
I was able to get the "sub-fragment" to display, and clicking on the back button will take me to the previous fragment which is what I want.
My problem is that when I click on another tab, the "sub-fragment" isn't going away. And if I click the back button, I get an IllegalStateException saying Fragment1 has already been added.
Here is some of the code which hopefully will help answer my question.
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);
}
}
Fragment1:
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();
}
}
This is written in Xamarin (C#), but I do understand Java code, so any help/examples using Java are fine.
Update:
I realized that my MainActivityLayout.axml file was using a RelativeLayout instead of a FrameLayout this is why I had to use attach/detach instead of show/hide. Here is my new layout:
<?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>
It still isn't working as expected, but I don't get the exception anymore saying the fragment has already been added.
Update 2:
I've decided to scrap trying to use the OnTabSelected and OnTabUnselected and just use delegates since I'm using C#. The important code is this:
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);
}
I think what you need to do is save a reference to SubFragment
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();
}
Then when Fragment1 is detatched, remove the subFrag
@Override public void onDetach() {
if (subFrag != null) {
FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction();
fragmentTransaction.Remove(subFrag );
fragmentTransaction.Commit();
}
super.onDetach();
}
Another (though a bit crude in my opinion) option could be to implement a getSubFragment()
method in Fragment1 and do:
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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.