В чем преимущество использования фрагментов в Android, а не представлений?


102

При разработке для Androidцелевого (или минимального) sdk можно установить значение 4 (API 1.6) и добавить пакет совместимости с Android (v4), чтобы добавить поддержку Fragments. Вчера я сделал это и успешно реализовал Fragmentsдля визуализации данных из пользовательского класса.

У меня такой вопрос: в чем преимущество использования Fragmentsпо сравнению с простым получением View из настраиваемого объекта, при этом поддерживая API 1.5?

Например, скажем, у меня есть класс 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

Оба метода очень просто создать и работать с ним в Activity, который, скажем, должен List<Foo>отображать (например, программно добавляя каждый к a ScrollView), так что они Fragmentsдействительно полезны, или они просто преувеличенное упрощение получить представление, например, с помощью кода выше?


2
У фрагментов не обязательно должен быть пользовательский интерфейс, они могут быть просто повторно используемыми. В этом случае View будет излишним.
Филипп Рейхарт

Я ответил на это другим вопросом. См. Stackoverflow.com/a/14912608/909956 T; dr - иногда фрагменты позволяют создавать больше повторно используемых компонентов, чем полагаться на реализацию пользовательского представления. см. ссылку, почему.
Нуман Салати

Ответы:


172

Основная причина использования фрагментов - это функции backstack и жизненного цикла. В противном случае настраиваемые представления более легкие и проще в реализации.

Сначала я действительно пытался создать приложение для телефона / планшета, используя настраиваемые представления. Все появились на работу через телефоны и таблетки, даже переход от одной панели к раздельным панели. У меня проблемы с кнопкой «Назад» и жизненным циклом. Поскольку я просто обновлял представления вручную ... не было ничего, что могло бы отслеживать историю представлений и их состояния. Следовательно, кнопка «Назад» не работала должным образом, и было сложно воссоздать даже последнее состояние во время событий жизненного цикла, например, при повороте приложения. Чтобы исправить это, мне пришлось обернуть свои пользовательские представления во фрагменты и использовать FragmentManager, чтобы предыдущие состояния были сохранены и воссозданы.

После ответа я понял, что отправил на аналогичный вопрос годом ранее: https://stackoverflow.com/a/11126397/618881


14
Очень хороший ответ. Я просто хотел добавить, что фрагменты могут быть вложенными, начиная с версии 4.2 или библиотеки поддержки rev 11.
Кар

2
Спасибо @Karlo за обновление. Я не думал, что это концептуально возможно, но они решили обойти это, используя частный FragmentManager через getChildFragmentManager (). Да, и это API 17, а не 11, и он доступен через библиотеку поддержки.
Генри

2
Я просто снова смотрел на этот вопрос, и мой опыт тоже изменился. Это очень полезный ответ, который дает хорошее понимание как преимуществ, так и недостатков. Спасибо!
Фил

2
Хотите +1 к этому ответу, но это испортит текущий счет. К тому же 70 - не мое любимое число.
Behnam

1
в прошлом году я также думал, что фрагменты не предоставляют никаких дополнительных обычных функций, но я испытал, что после повторного нажатия на активность я терял все загруженные изображения, поэтому мне пришлось добавить реализацию кеша, теперь я думаю использовать фрагменты это может быть очень просто
Шириш Хервэйд

27

Я бы сказал, что фрагменты полезны в двух сценариях: если вы разделяете представления на некоторых устройствах / ориентациях и показываете их в двух действиях и показываете весь контент в одном на других устройствах. Это будет вариант использования, если вы используете планшет или, возможно, даже в ландшафтном режиме на телефоне: например, вы показываете список элементов и детали на одном экране. на телефоне или в портретном режиме вы показываете только одну часть.

Другой вариант использования - многократно используемые представления. Поэтому, если у вас есть представления, которые видны для разных действий, а также выполняют некоторые действия, вы можете поместить это поведение во фрагмент, а затем повторно использовать его. Очевидно, вы могли бы сделать это и с пользовательскими виджетами.

Я не вижу причин использовать фрагменты для каждого представления, и я думаю, что это будет просто накладными расходами. Я использую их только в первом случае, и я бы сказал, что здесь это упрощение.


Спасибо, это было определенно полезно. Я думаю, что буду придерживаться представлений и сделаю свой собственный «задний стек», чтобы сделать их многоразовыми.
Фил

3

Android представил фрагменты в Android 3.0 (уровень API 11), в первую очередь для поддержки более динамичного и гибкого дизайна пользовательского интерфейса на больших экранах, таких как планшеты. Поскольку экран планшета намного больше, чем у телефона, есть больше места для объединения и обмена компонентами пользовательского интерфейса. Фрагменты позволяют создавать такие конструкции без необходимости управлять сложными изменениями иерархии представлений. Разделив макет действия на фрагменты, вы можете изменить внешний вид действия во время выполнения и сохранить эти изменения в заднем стеке, которым управляет действие.

Здесь вы можете узнать больше.


Я прочитал всю документацию, однако я искал что-то, что лучше объясняет их преимущества, например, для планшетов или backstack
Фил

3
  1. Сценарий Activity Split screen - у нас есть один макет и одно действие, которое обрабатывает левую и правую часть экрана.
  2. Сценарий FragmentActivity у нас есть один макет для главного экрана, один для левого и правый

Первый сценарий хорош, если у вас простое приложение.

Второй сценарий хорош, если вы хотите иметь несколько фрагментов и несколько объектов FragmentActivities, и вы можете комбинировать каждый из них. Также вы можете производить взаимодействие между фрагментами.

У меня есть разделенный экран Fragmentactivity, я могу вызвать его с помощью «Intent Extras» и сообщить fragmentActivity, какой фрагмент должен быть загружен. Фрагменты хороши тем, что их нет в манифесте, поэтому вы можете создавать повторно используемые фрагменты и FragmentActvity.

Но это делает ваш проект больше. Но если вы сделаете большой проект, вы можете сэкономить много. Потому что вы можете использовать те же фрагменты или одно и то же действие фрагмента.

И мне кажется, что эти фрагменты приходят немного поздно, поэтому вы должны попробовать мыслить по-новому. Возможно, просто попробуйте преобразовать свою активность в FragmentActivity. Позже попробуйте найти повторно используемый код и сделать из него фрагмент.

Это полезно, но я не знаю, как прямо сейчас. Но у меня есть идеи.

Это всегда проблема. Команда Android что-то придумала, и никто не знает, для чего это нужно. Потому что мы вряд ли учимся так, как было, и здесь появляются новые вещи.

На мой взгляд, это хорошо, но не по той причине, которую нам сообщает Google.


0

Добавьте один случай при использовании фрагмента или действия поверх CustomView:

Когда вы используете CursorLoader для наблюдения за определенными представлениями, ListView или TextView и хотите обновлять их отображаемое значение всякий раз, когда данные вашего ContentProvider обновляются на сервере (наиболее распространенный случай, когда у вас есть служба, которая обновляет вашу локальную базу данных, периодически опрашивая данные из удаленной базы данных / облака )


-2

Одна важная вещь, о которой не упоминается во всех приведенных выше комментариях, заключается в том, что фрагмент остается резидентным в памяти, даже если Android убивает активность и перезапускает ее, когда вы делаете что-то вроде изменения ориентации своего устройства. Это делается из соображений производительности, но также может привести к неожиданным результатам, если вы ожидали, что фрагменты будут уничтожены только для того, чтобы обнаружить, что они воссоздаются из ниоткуда.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.