Необходим комплексный дизайн интерфейса 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();
Фрагмент, который я добавлял, тогда знал, где закрепить себя в текущем макете, и, конечно же, поехал вокруг этого веселого способа добавить его в представление. Это привело к прикреплению фрагмента к другому фрагменту, следовательно, к достижению желаемого визуального "гнездования"...