2012-01-30 11 views
10

W przypadku użycia fragmentów w dokumentach systemu Android, gdy aplikacja działa w trybie "podwójnego podglądu", fragment szczegółów jest odtwarzany, gdy aplikacja musi wyświetlać szczegóły dotyczące innego tytułu. FragmentTransaction.replace() służy do zamiany każdej starej instancji fragmentu szczegółów na nową.OK, aby zaktualizować fragmenty zamiast tworzyć nowe instancje?

Czy to zalecana praktyka? Czy tworzenie nowej instancji interfejsu użytkownika nie jest marnotrawstwem, gdy prawdziwym intencją (gra słów nie jest przeznaczona) jest aktualizacja tego, co pokazuje interfejs użytkownika, a nie sam interfejs. Wydaje mi się, że jedynym powodem tworzenia nowych instancji jest zamiar dodania ich do backstack, aby użytkownik mógł odtworzyć kroki. W przeciwnym razie czy można bezpiecznie zaktualizować fragment bezpośrednio?

W przypadku przykładu oznaczałoby to metodę zgodną z DetailsFragment.setShownIndex(). Zostanie to nazwane, przekazując nowy indeks tytułowy, zamiast odtwarzać DetailsFragment.

Załóżmy, że mamy wersję przykładu, w którym jedno działanie zarządza obydwoma fragmentami, ale pokazuje tylko jeden po drugim, zamieniając każdy fragment w razie potrzeby. Czy byłoby dobrze, aby w ramach działania utworzono instancję każdego fragmentu, zachowano odniesienia do każdej z nich, a następnie po prostu dodawałem lub usuwano te dwa wystąpienia z siebie w razie potrzeby?

Jedną z możliwych konsekwencji jest to, że gdy fragment tytułu znajduje się w stanie resumed (tj. Na "pierwszym planie"), wybór tytułu spowoduje wywołanie do DetailsFragment.setShownIndex() w czasie, gdy fragment szczegółów jest w stopped stan.

Dobry pomysł? Kiepski pomysł?

Z góry dziękuję.

Odpowiedz

5

Tak jak powiedziałeś, głównym powodem tworzenia nowych instancji Fragment jest łatwość użycia tylnego stosu. Całkowicie bezpieczne jest również ponowne użycie istniejącego fragmentu (sprawdzenie go za pomocą albo FragmentManager.findFragmentById() lub FragmentManager.findFragmentByTag()). Czasami trzeba dobrze wykorzystać metody Fragmentu, takie jak isVisible(), isRemoving() itd., Więc nie można bezprawnie odwoływać się do komponentów interfejsu użytkownika, gdy DetailsFragment jest stopped.

każdym razie w proponowanego działania jednego panelu 2 fragmenty, metoda setShownIndex może ustawić pole w DetailsFragment prywatnym, który jest ładowany w onCreateView lub onActivityCreated.

np

DetailsFragment df = getFragmentManager().findFragmentByTag("details"); 
if (df != null) { 
    df.setShownIndex(getSelectedIndex()); 
} else { 
    df = DetailsFragment.newInstance(getSelectedIndex()); 
} 
fragmentTransaction.replace(R.id.frame, df, "details").commit(); 

W obu przypadkach, zarówno df nowoutworzone lub ponownego użycia, onCreateView i onActivityCreated zostanie wywołana, gdy DetailsFragment jest dodawany do pojemnika.

Ale jeśli chcesz mieć tylny stos, bardzo zalecam tworzenie nowych instancji, w przeciwnym razie zaimplementujesz własny stos tylny dla zawartości DetailsFragment.

0

Próbowałem następujący kod i działa dla mnie:

private void replaceFragment(Class fragmentClass, String FRAGMENT_NAME, android.support.v4.app.FragmentManager fragmentManager) { 

    Fragment fragment = null; 
    String backStateName = fragmentClass.getName(); // nome della classe del Fragment 

    Log.d("Fragment: ", "Creazione Fragment: "+backStateName); 


    Boolean fragmentExit = isFragmentInBackstack(fragmentManager, backStateName); 


    if (fragmentExit) { //Il Fragment è presente nello stacback 

     // Fragment exists, go back to that fragment 
     //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow 
     fragmentManager.popBackStackImmediate(fragmentClass.getName(), 0); 

    } else { 

     // se non esiste lo aggiungiamo 
     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // Inizializzo la transazione del Fragment 
     android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction(); 
     ft.setCustomAnimations(
       R.anim.fragment_slide_left_enter, 
       R.anim.fragment_slide_left_exit, 
       R.anim.fragment_slide_right_enter, 
       R.anim.fragment_slide_right_exit); 
     ft.replace(R.id.frameLayout_contentMain, fragment, FRAGMENT_NAME); 
     ft.addToBackStack(fragmentClass.getName()); 
     ft.commit(); 

     // Recupero il numero di Fragment presenti 
     Integer nFragment = fragmentManager.getBackStackEntryCount(); 

     Log.d("Fragment: ", "Numero di Fragment: "+nFragment); 

    } 

} 

Aby ustalić, czy fragment jest już w StackBack wykonać tę funkcję:

public static boolean isFragmentInBackstack(final android.support.v4.app.FragmentManager fragmentManager, final String fragmentTagName) { 
    for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) { 
     if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) { 
      return true; 
     } 
    } 
    return false; 
} 

Mam nadzieję, że mogę pomóc

+0

byłby bardziej pomocny, gdybyś dostarczył komentarze w języku angielskim. –

+0

Przykro mi, ale jestem włochem. –

Powiązane problemy