2011-07-13 13 views
20

Rozważmy app próbki z developers.android.comFragmenty - Czy musisz używać Owijacza aktywności wokół fragmentu, który obejmuje całą Aktywność?

ten opisuje zastosowanie fragmentów tak:

  • z telefonu można wykorzystać Fragment 1 na aktywność A i fragment 2 na aktywność B.
  • Na tabletu mieć więcej nieruchomości, więc używaj Fragmentu 1 i Fragmentu 2 na Aktywność A.

Świetnie! ... Ale ... Na pierwszym przykładzie (tym z telefonem) tworzysz działanie z plikiem xml zawierającym pojedynczy <fragment> i to wszystko w działaniu, które nazywasz tylko setContentView() tym xmlem? Wydaje się, że wiele zbędnego kodu (Activity, XML & Fragment, aby wyświetlić fragment): Czy można ustawić Fragment jako Activity lub czy Owijacz z XML jest zawsze wymagany?

Odpowiedz

34

Ach, okazało się, że here

public class MainMenuHolder extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     // If not already added to the Fragment manager add it. If you don't do this a new Fragment will be added every time this method is called (Such as on orientation change) 
     if(savedInstanceState == null) 
      getSupportFragmentManager().beginTransaction().add(android.R.id.content, new MainMenuFragment()).commit(); 
    } 
} 

FragmentActivity pozwolić ty, aby ustawić jako fragment treści android.R.id.content które zakładam jest android wewnętrzny identyfikator widoku bagażnika.

Za pomocą tej metody nadal otrzymujesz przeważającą aktywność (Jeśli chcesz tylko Fragment działający jako Aktywność). Wciąż jednak o połowę mniej niż o aktywności i plik XML działający jak kontener.

Wszelkie inne odpowiedzi będą mile widziane!

+1

przyjmowanie rozwiązanie krok wybiegające tworzyć generic 'SingleFragmentActivity' ten fragment jako parametr konstruktora i dodaj go' onCreate'. następnie użyj tego działania za każdym razem, gdy potrzebujesz aktywności pojedynczego fragmentu. – shem

+2

@shem - Robię dokładnie to samo - przekazuję nazwę kanoniczną Fragment jako działanie, aby można było utworzyć instancję z ciągu. – Graeme

+0

Cóż, możesz także przestać używać Fragmentów, chyba że faktycznie potrzebujesz. W większości przypadków użycie prostego działania sprawiłoby tak samo dobrze –

2

Przykład online nie wypełnia wszystkich pustych miejsc. Spróbuję odpowiedzieć na twoje pytania bezpośrednio:

"Na pierwszym przykładzie (tym z telefonem) powinieneś utworzyć działanie z plikiem xml zawierającym pojedynczy i działanie, które wywołuje tylko setContentView() na tym xml i to wszystko?"

Zacząłeś we właściwym miejscu. Ale to coś więcej. Zawsze istnieje więcej niż jeden sposób rozwiązania problemu w systemie Android, ale zalecany sposób generowania efektu posiadania dynamicznej liczby fragmentów na podstawie dostępności. Nieruchomości to:

  1. Tworzenie plików układ XML w/układ dla głównego (domyślnie) ukierunkowane orientacja/urządzenia/form-factor/SDK
  2. Tworzenie układu plików XML dla najmniejszych szerokości odniesienia dla innych ukierunkowanej pomysłowość. Możesz również chcieć kierować inne orientacje, zestawy SDK itp.
  3. Każdy plik XML układu będzie miał swój własny zestaw zdefiniowanych fragmentów.
  4. W Aktywności sprawdź, które fragmenty są obecne.

Oczywiście można zastosować analogiczną strategię dla układów programowych.

W przykładzie w oryginalnym pytanie (z Dokumentów Google) można mieć:

  • układ/main.XML :: ten układ musiałby tylko Fragment 1
  • layout-sw600dp/main.xml :: ten układ musiałby Fragments 1, 2

Następnie w MainActivity.java chcesz sprawdzić istnienie każdego fragmentu . Aby to zrobić, możesz użyć FragmentManager # findFragmentById(), aby sprawdzić: if findFragmentById() zwraca null dla Fragment-2, a MainActivity wie, że urządzenie załadowało layout/main.xml i obsługuje tylko jeden fragment.

Krok "wróć" z przykładu nieco ujawnia, że: przed użyciem Fragmentów mógłbyś nazwać Aktywność B z Aktywności A z startAcitityForResult (int). W paradygmacie Fragment prawdopodobnie potrzebujesz tylko wyniku z Fragmentu 2, aby spowodować coś, co może się wydarzyć w Fragmencie 1, więc rozsądne jest, aby MainActivity był tym gatunkiem strażnikiem. W miarę rozwijania przykładu możesz zauważyć, że w innych aplikacjach usługa MainActivity może wymagać wywoływania innych działań - z dowolnego powodu. Być może celujesz w duży tablet z wystarczającą ilością nieruchomości na 3 fragmenty, ale na telefonie, który musi być 3 czynnościami. Rzeczy mogą się zainteresować, ale Fragment API jest dość potężny.

"Czy można ustawić Fragment jako działanie lub czy Wrapper jest zawsze potrzebny do używania fragmentów?"

Fragment nie jest aktywnością. Rzeczywiście Fragmenty są ładowane przez Działania, więc tak, można powiedzieć, że zawsze wymagane jest opakowanie. Dotykasz innego subtelnego aspektu Fragmentów. Podczas gdy Działania zachowują się jak Kontrolery MVC, Fragmenty mogą być nazywane "mini-kontrolerami" ze względu na ich cykl życiowy, który zarówno przypomina jak i wykonuje wraz z Działaniem. Ponownie, cykl życia Fragmentu jest zawarty wewnątrz ("owinięty przez") cyklem życia Działania zarządzającego Fragmentem. Polecam zapoznanie się z cyklem życia Fragmentu udokumentowanym pod numerem http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle.

+10

Nie mam pojęcia, co tu odpowiadasz ...? – Graeme

1

Bardziej ogólnie można utworzyć klasę pojemnik fragment:

public class SingleFragmentActivity extends Activity { 

    public static final String FRAGMENT_NAME = "fragmentName"; 
    public static final String FRAGMENT_ARGUMENTS = "fragmentArguments"; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     String fragmentName = getIntent().getStringExtra(FRAGMENT_NAME); 
     Fragment fragment = Fragment.instantiate(this, fragmentName); 
     Bundle fragmentArguments = getIntent().getBundleExtra(FRAGMENT_ARGUMENTS); 
     fragment.setArguments(fragmentArguments); 
     getSupportFragmentManager().beginTransaction().replace(android.R.id.content,fragment, "tag").commit(); 
    } 
} 

teraz użyć tej klasy do wystąpienia dowolnego fragmentu jako samodzielna działalność:

public void showFragmentAsActivity() { 
    Intent intent = new Intent(this, SingleFragmentActivity.class); 
    intent.putExtra(SingleFragmentActivity.FRAGMENT_NAME, MyFragment.class.getName()); 
    intent.putExtra(SingleFragmentActivity.FRAGMENT_ARGUMENTS,MyFragment.getArgumentsBundle("a string argument")); 
    startActivity(intent); 
} 
Powiązane problemy