Jaka jest korzyść z używania fragmentów w systemie Android, a nie widoków?

102

Podczas programowania dla Androidmożesz ustawić docelowy (lub minimalny) pakiet SDK na 4 (API 1.6) i dodać pakiet zgodności dla systemu Android (v4), aby dodać obsługę Fragments. Wczoraj zrobiłem to i pomyślnie zaimplementowałem Fragmentswizualizację danych z niestandardowej klasy.

Moje pytanie brzmi: jaka jest korzyść z używania Fragmentsw przeciwieństwie do zwykłego uzyskiwania widoku z niestandardowego obiektu i nadal obsługującego API 1.5?

Na przykład, powiedzmy, że mam klasę 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 utworzenia i pracy w działaniu, które, powiedzmy, ma List<Foo>do wyświetlenia (na przykład programowe dodawanie każdej z nich do a ScrollView), więc są Fragmentsnaprawdę bardzo przydatne, czy też są po prostu przesadnym uproszczeniem uzyskiwanie widoku, na przykład za pomocą powyższego kodu?

Phil
źródło
2
Fragmenty nie muszą mieć interfejsu użytkownika, mogą być po prostu zachowaniem wielokrotnego użytku. Widok byłby w takim przypadku zbędny.
Philipp Reichart,
Odpowiedziałem na to w innym pytaniu. Zobacz stackoverflow.com/a/14912608/909956 T; dr - czasami fragmenty pozwalają na tworzenie komponentów wielokrotnego użytku w większym stopniu niż poleganie na niestandardowej implementacji widoku. zobacz link, aby dowiedzieć się, dlaczego.
numan salati

Odpowiedzi:

172

Głównym powodem używania fragmentów są funkcje backstack i cyklu życia. W przeciwnym razie widoki niestandardowe są lżejsze i prostsze do wdrożenia.

Początkowo próbowałem zbudować aplikację na telefon / tablet, używając niestandardowych widoków. Wszystko wydawało się działać na telefonach ORAZ tabletach, nawet przełączając się z jednego panelu na podzielony panel. Problem dotyczył przycisku Wstecz i cyklu życia. Ponieważ po prostu aktualizowałem widoki ręcznie ... nic nie śledziło historii widoków 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, takich jak obracanie aplikacji. Aby to naprawić, musiałem zawinąć moje widoki niestandardowe we fragmenty i użyć FragmentManager, aby poprzednie stany zostały zapisane i odtworzone.

Po udzieleniu odpowiedzi zdałem sobie sprawę, że rok wcześniej wysłałem na podobne pytanie: https://stackoverflow.com/a/11126397/618881

Henz
źródło
14
Bardzo dobra odpowiedź. Chciałem tylko dodać, że fragmenty można zagnieżdżać od 4.2 lub wspierać bibliotekę rev 11.
kar
2
Dzięki @Karlo za aktualizację. Nie sądziłem, że jest to koncepcyjnie możliwe, ale obejrzeli to, używając prywatnego FragmentManagera za pośrednictwem getChildFragmentManager (). Aha, i to jest API 17, a nie 11 i jest dostępne w bibliotece pomocy technicznej.
Henry,
2
Właśnie ponownie spojrzałem na to pytanie i moje doświadczenie też się zmieniło. Jest to odpowiedź, która zapewnia dobre zrozumienie zarówno zalet, jak i wad, i jest bardzo pomocna. Dzięki!
Phil
2
Chcesz dać +1 tej odpowiedzi, ale zrobienie tego zrujnowałoby obecny wynik. Poza tym 70 nie jest moją ulubioną liczbą.
Behnam
1
przez ostatni rok myślałem również, że Fragmenty nie zapewniają żadnej dodatkowej zwykłej funkcji, ale doświadczyłem, że po kliknięciu z powrotem na aktywność traciłem wszystkie pobrane obrazy, więc musiałem dodać implementację pamięci podręcznej, teraz myślę o użyciu fragmenty może być bardzo łatwe
Shirish Herwade
27

Powiedziałbym, że fragmenty są przydatne w dwóch scenariuszach: jeśli podzielisz widoki na niektóre urządzenia / orientacje i pokażesz je w dwóch działaniach i pokażesz całą zawartość w jednym na innych urządzeniach. Byłby to przypadek użycia, jeśli korzystasz z tabletu, a może nawet w trybie poziomym na telefonie: np. Pokazujesz listę elementów i szczegóły na jednym ekranie. na telefonie lub w trybie portretowym po prostu pokazujesz jedną część.

Innym przypadkiem 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 czynności, możesz umieścić to zachowanie we fragmencie, a następnie użyć go ponownie. Oczywiście możesz to zrobić również za pomocą niestandardowych widżetów.

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

Maria Neumayer
źródło
Dzięki, to było zdecydowanie pomocne. Myślę, że pozostanę przy widokach i stworzę własny „tylny stos”, aby umożliwić ich ponowne użycie.
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ż w telefonie, jest więcej miejsca na łączenie i wymianę elementów interfejsu użytkownika. Fragmenty pozwalają na takie projekty bez konieczności zarządzania złożonymi zmianami w hierarchii widoków. Dzieląc układ działania na fragmenty, można modyfikować wygląd działania w czasie wykonywania i zachować te zmiany w stosie wstecznym zarządzanym przez działanie.

Tutaj możesz przeczytać więcej.

Yury
źródło
Przeczytałem całą dokumentację, jednak szukałem czegoś, co lepiej wyjaśnia ich zalety, na przykład tabletów lub backstacka
Phil
3
  1. Scenariusz Czynność Podzielony ekran - Mamy jeden układ i jedną czynność, która obsługuje lewą prawą część ekranu
  2. Scenario FragmentActivity Mamy jeden układ dla ekranu głównego, jeden dla lewego, jeden dla prawego

Scenariusz pierwszy jest dobry, jeśli masz prostą aplikację.

Scenariusz drugi jest dobry, jeśli chcesz mieć wiele fragmentów i wiele działań fragmentarycznych i możesz połączyć każdy z nich. Możesz także dokonywać interakcji między fragmentami.

Mam podzielony ekran Fragmentactivity, mogę to nazwać „Intent Extras” i powiedzieć fragmentActivity, który fragment ma zostać załadowany. Fragmenty są dobre, ponieważ nie są widoczne, więc możesz utworzyć fragmenty wielokrotnego użytku i FragmentActvity.

Ale to sprawia, że ​​twój projekt jest większy. Ale jeśli zrobisz duży projekt, możesz zaoszczędzić wiele. Ponieważ możesz użyć tych samych fragmentów lub tej samej aktywności fragmentów.

I wydaje mi się, że te fragmenty przychodzą trochę późno, 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 utwórz z niego fragment.

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

To zawsze jest problem. Android Team coś wymyślił i nikt nie wie, do czego służy. Ponieważ prawie nie uczymy się tak, jak było, a tu pojawia się kilka nowych rzeczy.

Moim zdaniem to dobrze, ale nie z tego powodu, że Google mówi nam.

Mertuarez
źródło
0

Dodaj jeden przypadek, gdy używasz fragmentu lub działania zamiast widoku niestandardowego:

Gdy używasz CursorLoader do obserwowania pewnych widoków, ListView lub TextView i chcesz zaktualizować ich wartość wyświetlaną za każdym razem, gdy dane Twojego ContentProvidera aktualizują się na zapleczu (najczęściej masz usługę, która aktualizuje lokalną bazę danych przez okresowe odpytywanie danych ze zdalnej bazy danych / chmury )

macio.Jun
źródło
-2

Jedną wielką rzeczą, o której wszystkie powyższe komentarze nie wspominają, jest to, że fragment pozostaje w pamięci, nawet jeśli Android zabije aktywność i uruchomi ją ponownie, gdy zrobisz coś takiego, jak zmiana orientacji urządzenia. Odbywa się to ze względu na wydajność, ale może również prowadzić do nieoczekiwanych rezultatów, jeśli spodziewasz się, że fragmenty zostaną zniszczone tylko po to, aby stwierdzić, że są odtwarzane znikąd.

AndroidDev
źródło