2011-12-23 19 views
98

Podczas opracowywania dla Android, możesz ustawić swój cel (lub minimum) sdk na 4 (API 1.6) i dodać pakiet kompatybilności z systemem Android (v4), aby dodać obsługę dla Fragments. Wczoraj zrobiłem to i pomyślnie zaimplementowałem Fragments, aby wizualizować dane z niestandardowej klasy.Jaka jest korzyść z używania Fragmentów w systemie Android zamiast z widoków?

Moje pytanie brzmi następująco: jaka jest korzyść z używania Fragments, a nie po prostu uzyskiwanie widoku z niestandardowego obiektu i obsługa API 1.5?

Załóżmy, że mam klasy Foo.java:

public class Foo extends Fragment { 

    /** Title of the Foo object*/ 
    private String title; 
    /** A description of Foo */ 
    private String message; 

    /** Create a new Foo 
    * @param title 
    * @param message */ 
    public Foo(String title, String message) { 
     this.title = title; 
     this.message = message; 
    }//Foo 

    /** Retrieves the View to display (supports API 1.5. To use, 
    * remove 'extends Fragment' from the class statement, along with 
    * the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}) 
    * @param context Used for retrieving the inflater */ 
    public View getView(Context context) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View v = inflater.inflate(R.layout.foo, null); 
     TextView t = (TextView) v.findViewById(R.id.title); 
     t.setText(this.title); 
     TextView m = (TextView) v.findViewById(R.id.message); 
     m.setText(this.message); 
     return v; 
    }//getView 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     if (container == null) { 
      return null; 
     } 
     View v = inflater.inflate(R.layout.foo, null); 
     TextView t = (TextView) v.findViewById(R.id.title); 
     t.setText(this.title); 
     TextView m = (TextView) v.findViewById(R.id.message); 
     m.setText(this.message); 
     return v; 
    }//onCreateView 

}//Foo 

Obie metody są bardzo proste do tworzenia i pracować w działalność, która, powiedzmy, ma List<Foo> do wyświetlania (na przykład, programowo dodając każdy z nich do ScrollView), tak naprawdę są przydatne, czy są po prostu przesadnie uproszczonym sposobem uzyskania widoku, na przykład za pomocą powyższego kodu?

+2

Fragmenty nie muszą mieć interfejsu użytkownika, mogą po prostu być zachowaniem wielokrotnego użytku. Widok byłby wówczas zbędny. –

+0

Odpowiedziałem na to w innym pytaniu. Zobacz http://stackoverflow.com/a/14912608/909956 T; dr - czasami fragmenty pozwalają tworzyć więcej komponentów wielokrotnego użytku niż polegać na niestandardowej implementacji widoku. zobacz link z tego powodu. –

Odpowiedz

162

Głównym powodem używania Fragmentów są funkcje backstack i lifecycle. W przeciwnym razie niestandardowe widoki są lżejsze i łatwiejsze do wdrożenia.

Początkowo próbowałem zbudować aplikację na telefon/tablet przy użyciu niestandardowych widoków. Wszystko pojawił się do pracy na telefonach I tabletów, a nawet przełączania z jednego panelu na podzielony panel. Tam, gdzie wpadłem w kłopoty, znajdował się przycisk powrotu i cykl życia. Ponieważ po prostu aktualizowałem widoki ręcznie ... nie było nic, co pozwalałoby śledzić historię wyświetleń i ich stanów. Dlatego przycisk Wstecz nie działał zgodnie z oczekiwaniami i trudno było odtworzyć nawet najnowszy stan podczas wydarzeń cyklu życia, na przykład podczas obracania aplikacji. Aby to naprawić, musiałem zawijać własne widoki w fragmentach i używać FragmentManagera, aby poprzednie stany były zapisywane i odtwarzane.

zdałem sobie sprawę, po odpowiedzi, że pisał w podobnym pytaniem rok wcześniej:https://stackoverflow.com/a/11126397/618881

+14

Bardzo dobra odpowiedź. Chciałem tylko dodać, że fragmenty mogą być zagnieżdżone od wersji 4.2 lub biblioteki wsparcia rev 11. –

+2

Dzięki @Karlo za aktualizację.Nie sądziłem, że było to możliwe z koncepcyjnego punktu widzenia, ale pracowali nad tym przy użyciu prywatnego FragmentManager poprzez getChildFragmentManager(). Aha, i to jest API 17, a nie 11, i dostępne za pośrednictwem Biblioteki Wsparcia. – Henry

+2

Właśnie patrzyłem na to pytanie ponownie, i moje doświadczenie też się zmieniło. Jest to odpowiedź, która zapewnia dobre zrozumienie zarówno korzyści, jak i wad i jest bardzo pomocna. Dzięki! – Phil

27

Powiedziałbym, że Fragmenty są użyteczne w dwóch scenariuszach: jeśli podzielisz widoki na niektóre urządzenia/orientacje i pokaż je w dwóch działaniach i pokaż całą treść w jednym na innych urządzeniach. To byłby przypadek użycia, jeśli przejdziesz na tablet, a może nawet w trybie poziomym na telefonie: np. wyświetlasz listę przedmiotów i szczegóły na jednym ekranie. na telefonie lub w trybie portretowym pokazujesz tylko jedną część.

Innym przykładem użycia są widoki wielokrotnego użytku. Więc jeśli masz jakieś widoki, które są widoczne w różnych działaniach, a także wykonujesz pewne akcje, możesz umieścić to zachowanie w fragmencie, a następnie użyć go ponownie. Oczywiście prawdopodobnie możesz to zrobić również za pomocą niestandardowych widgetów.

Nie widzę powodu, aby używać Fragmentów dla każdego Widoku i myślę, że byłby to tylko koszt. Używam ich tylko w pierwszym przypadku użycia i powiedziałbym, że jest to uproszczenie.

+0

Dzięki, to było zdecydowanie pomocne. Myślę, że pozostanę przy poglądach i zrobię swój własny "back-stack", aby umożliwić ich ponowne wykorzystanie. – Phil

3

Android wprowadził fragmenty w systemie Android 3.0 (poziom interfejsu API 11), głównie w celu obsługi bardziej dynamicznych i elastycznych projektów interfejsu użytkownika na dużych ekranach, takich jak tablety. Ponieważ ekran tabletu jest znacznie większy niż ekran telefonu, jest więcej miejsca na łączenie i wymianę komponentów interfejsu użytkownika. Fragmenty pozwalają na takie projekty bez potrzeby zarządzania złożonymi zmianami w hierarchii widoku. Dzieląc układ działania na fragmenty, można modyfikować wygląd działania w środowisku wykonawczym i zachować te zmiany w tylnym stosie, który jest zarządzany przez działanie.

Here możesz przeczytać więcej.

+0

Przeczytałem całą dokumentację, jednak szukałem czegoś, co lepiej tłumaczy ich korzyść, na przykład dla tabletów lub backstack. – Phil

3
  1. Scenariusz podzielonym ekranie aktywny - mamy jeden układ i jedno działanie, które przerabiają lewo prawej części ekranowego
  2. Scenario FragmentActivity mamy jeden układ dla głównego ekranu, jeden dla lewego jeden dla prawego

Scenariuszu jeden jest dobry, jeśli masz prostą aplikację.

Scenariusz drugi jest dobry, jeśli chcesz mieć wiele fragmentów i wiele funkcji fragmentacji i możesz łączyć je wszystkie. Możesz także dokonywać interakcji między fragmentami.

Mam podzielony ekran Fragmentactivity, który można nazwać "Intent Extras" i powiedzieć fragmentacji Aktywność, który fragment ma zostać załadowany.Fragmenty są dobre, ponieważ nie są widoczne, więc można tworzyć wielokrotne fragmenty i FragmentActvity.

Ale to zwiększa twój projekt. Ale jeśli zrobisz duży projekt, możesz zaoszczędzić wiele. Ponieważ możesz używać tych samych fragmentów lub tej samej aktywności fragmentu.

Rzecz w tym, że te fragmenty się spóźniają, więc musisz spróbować myśleć w nowy sposób. Może po prostu spróbuj przekonwertować swoją aktywność na FragmentActivity. Później spróbuj znaleźć kod wielokrotnego użytku i z niego Utwórz Fragment.

Jest to przydatne, ale nie wiem jak teraz. Ale mam kilka pomysłów.

To zawsze jest problem. Zespół ds. Androida coś wymyślił i nikt nie wie, co jest dobre. Ponieważ prawie się nie uczymy, tak jak było, a tu pojawia się kilka nowych rzeczy.

Moim zdaniem to jest dobre, ale nie z powodu, że Google nam powiedzieć.

0

dodać jeden przypadek, gdy przy użyciu fragmentu lub aktywny ponad CustomView:

Kiedy używasz CursorLoader przestrzegać pewnych poglądów , ListView lub TextView i chcesz zaktualizować wyświetlaną wartość za każdym razem, gdy dane ContentProvider są aktualizowane z tyłu (najczęstszy przypadek, w którym masz usługę aktualizującą lokalną bazę danych, okresowo odpytując dane ze zdalnej bazy danych/chmury)

-2

Jedna wielka rzecz, o której nie wspominają powyższe komentarze, to fakt, że fragment pozostaje rezydentny w pamięci, nawet jeśli Android zabija aktywność i uruchamia ją ponownie, gdy robisz coś w rodzaju zmiany orientacji urządzenia. Odbywa się to ze względu na wydajność, ale może również prowadzić do nieoczekiwanych rezultatów, jeśli spodziewałeś się, że fragmenty zostaną zniszczone tylko wtedy, gdy zostaną odtworzone z nikąd.