Необходим комплексный дизайн интерфейса UI (фрагменты)

Я разрабатываю приложения, предназначенные для планшетов и Google TV. Он будет подобен многим стандартным приложениям Google TV с LeftNavBar и верхней панелью поиска, которая является общей для всех экранов приложений. Он будет выглядеть примерно так:

Основной экран enter image description here

Область RED будет отличаться для всех остальных экранов. Он может содержать такие данные, как следующие макеты экранов:

Действие 1 загружено в основной контейнер enter image description here

Действие Два загруженных в основной контейнер enter image description here

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

Экран 3 можно загрузить в виде подробного раздела при выборе любого элемента списка на экране 2 (скажем, в списке фрагментов) ИЛИ его можно загрузить в результате выбора вкладки (которая появится в LeftNavBar).

Вот как я пытаюсь его реализовать.

Шаг 1.. Я создал основное действие со следующим XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <FrameLayout
        android:id="@+id/mainContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <!-- main Red Container that will load other Activities -->

    </FrameLayout>
</LinearLayout>

mainContainer - это контейнер RED, где я хочу загрузить действия. LeftNavBar будет добавлен в эту активность как ее родительский элемент All.

Шаг 2 Я создал ActivityOne и ActivityTwo с двумя и тремя фрагментами в них соответственно (как показано на втором и третьем изображении).

* Шаг 3 Я пытаюсь загрузить ActivityOne на главной странице mainContainer FrameLayout... Но я не могу добавить его.

Я попытался добавить ActivityOne в mainContainer следующим образом:

View v = (new ActivityOne()).getWindow().getDecorView();
FrameLayout mainContainer = (FrameLayout) findViewById(R.id.mainContainer);
mainContainer.addView(v);

но getWindow() возвращает null....

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

ИЛИ

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

Что бы вы сделали, если бы вам пришлось создавать этот тип приложения? Как бы вы разработали макет пользовательского интерфейса для лучшей производительности/практики?

Ваши предложения в том, чтобы помочь мне настроить этот макет приложения, очень ценятся.

Ответ 1

Отказ

Здесь фрагменты могут оказаться сложными. Проблема была бы простой, если для действий 1 и 2 были одинаковые макеты, чтобы вы могли просто присоединить/отсоединить фрагменты и использовать стопку фрагмента для размотки.

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

В качестве другого варианта вы можете использовать два действия, как описано выше, и отправлять данные вперед и назад с помощью намерений.

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

Решение

Создайте FragmentActivity, чей вид будет основным экраном, как вы определили выше. Макет основного экрана будет содержать:

  • Левая панель навигации
  • Верхняя панель
  • 2 макета. layout1 и layout2. Они будут содержаться в родительском макете, то есть RelativeLayout или LinearLayout, и будут содержать необходимые элементы FrameLayout для ваших фрагментов.

Пример использования вашего XML (примечание, теги немного кратки):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#9ccc" >

        <!-- Top Bar -->

    </LinearLayout>

    <LinearLayout android:id="@+id/layout1">
        <FrameLayout android:id="@+id/listFragment" />
        <FrameLayout android:id="@+id/contentFragment" />
    </LinearLayout>

    <LinearLayout android:id="@+id/layout2">
        <FrameLayout android:id="@+id/imageFragment" />
        <FrameLayout android:id="@+id/boxFragment1" />
        <FrameLayout android:id="@+id/boxFragment2" />
        <FrameLayout android:id="@+id/boxFragment3" />
    </LinearLayout>

</LinearLayout>

Основная идея заключается в том, что вы затем показываете/скрываете layout1 и layout2, то есть устанавливаете android: visibility = "ушел" в зависимости от состояния вашего приложения.

Недостатками этого метода являются:

  • Использование фрагмента backstack может быть невозможно, вместо этого вам нужно будет отслеживать, где пользователь находится в потоке пользовательского интерфейса, и управлять кнопкой "Назад", чтобы отображать/скрывать макет.
  • Возможно, вам придется проявлять особую осторожность при прикреплении/отсоединении фрагментов, когда вы показываете/скрываете их родительское представление, чтобы уменьшить потребление ресурсов, пока фрагменты невидимы.

Преимущества:

  • Простая связь между фрагментами и базовой активностью, поскольку используется только 1 активность.

Ответ 2

Re: проблема с вложенными фрагментами

Чтобы обойти проблему "вложенных фрагментов" в нашем приложении, где (как вы правильно заметили) Fragment не может добавить Fragment У меня был один шаблонный фрагмент под действием, целью которого было определить набор держателей мест для других фрагментов для привязки. Добавляя дополнительные фрагменты к активности за этот момент, я использовал шаблонный держатель места размещения фрагмента [email protected] для идентификации идентификатора "root" или родительского представления для добавляемого фрагмента.

    getSupportFragmentManager().beginTransaction().add(#someIdFromTheTemplateFrag, fragment, fragmentTag).commit();

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