OK, w końcu zorientowaliśmy się:
Jak sugerowano powyżej, pierwszy zmieniłem tworzenie fragmentów do zrobienia programowo i miał je dodany do kierownika fragmentu dziecko, tak jak poniżej:
public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance)
{
var view = inflater.Inflate(Resource.Layout.MyView, viewGroup, false);
// Add fragments to the child fragment manager
// DONT DO THIS, SEE BELOW
var tx = ChildFragmentManager.BeginTransaction();
tx.Add(Resource.Id.lhs_fragment_frame, new LhsFragment());
tx.Add(Resource.Id.rhs_fragment_frame, new RhsFragment());
tx.Commit();
return view;
}
Zgodnie z oczekiwaniami, za każdym razem, gdy przełączałem karty, tworzone były dodatkowe instancje Lhs/RhsFragment, ale zauważyłem, że stary OnLeon/RhsFragment również zostanie wywołany. Tak więc po każdym przełączniku tabulacji byłoby jeszcze jedno wywołanie OnCreateView. Przełącz zakładki 10 razy = 11 połączeń do OnCreateView. Jest to oczywiście błędne.
Patrząc na kod źródłowy FragmentTabHost, widzę, że po prostu odłącza i ponownie dołącza fragment zawartości karty podczas przełączania kart. Wygląda na to, że nadrzędny Fragmentowy obiekt ChildFragmentManager zachowuje fragmenty potomne i automatycznie odtwarza ich widoki, gdy fragment macierzysty jest ponownie dołączany.
Więc przeniosłem tworzenie fragmentów do onCreate, i tylko wtedy, gdy nie jesteśmy ładowania z zapisanego stanu:
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (savedInstanceState == null)
{
var tx = ChildFragmentManager.BeginTransaction();
tx.Add(Resource.Id.lhs_fragment_frame, new LhsFragment());
tx.Add(Resource.Id.rhs_fragment_frame, new RhsFragment());
tx.Commit();
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance)
{
// Don't instatiate child fragments here
return inflater.Inflate(Resource.Layout.MyView, viewGroup, false);
}
To stałe tworzenie dodatkowych widoków i zakładka przełączania w zasadzie pracował teraz.
Następne pytanie dotyczyło zapisywania i przywracania stanu widoku. W fragmentach potomnych muszę zapisać i przywrócić aktualnie wybrany element. Pierwotnie miałem coś takiego (to fragment podrzędnego OnCreateView)
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance)
{
var view = inflater.Inflate(Resource.Layout.CentresList, container, false);
// ... other code ommitted ...
// DONT DO THIS, SEE BELOW
if (savedInstance != null)
{
// Restore selection
_selection = savedInstance.GetString(KEY_SELECTION);
}
else
{
// Select first item
_selection =_items[0];
}
return view;
}
Problem polega na tym, że host zakładka nie wymaga OnSaveInstanceState podczas przełączania kart. Zamiast tego fragment dziecka zostaje utrzymany przy życiu, a zmienna selekcji może zostać pozostawiona sama.
Więc przeniosłem kod zarządzać wybór do onCreate:
public override void OnCreate(Bundle savedInstance)
{
base.OnCreate(savedInstance);
if (savedInstance != null)
{
// Restore Selection
_selection = savedInstance.GetString(BK_SELECTION);
}
else
{
// Select first item
_selection = _items[0];
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance)
{
// Don't restore/init _selection here
return inflater.Inflate(Resource.Layout.CentresList, container, false);
}
Teraz to wszystko wydaje się być doskonale pracuje zarówno podczas przełączania kart i zmiany orientacji.
OK, to brzmi obiecująco. Jak mogę powiedzieć, że nadmuchiwacz używa menedżera fragmentów potomnych zamiast macierzystego? –
Dodajesz fragment podrzędny do wnętrza fragmentu macierzystego, używając kodu fragmentu nadrzędnego, używając programu ChildFragmentManager do dodania jego elementów podrzędnych. Następnie nadmuchiwania, które metoda callback onCreateView z części (dziecko) zapewnia: https://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle). –
Prawdopodobnie będziesz musiał wykonać więcej badań google/stackoverlowing, aby zobaczyć, jak radzić sobie z fragmentami potomnymi w Mono. Nie mogę ci tam pomóc (używam Java). –