Расположение координатора с панелью инструментов во фрагментах или действиях

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

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

Ответ 1

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

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

Предположим, что ваше поведение по умолчанию app:layout_behavior="@string/appbar_scrolling_view_behavior"

Затем в вашем файле fragment_activity_layout.xml может быть что-то вроде этого:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/dashboard_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.Toolbar"
            app:layout_scrollFlags="scroll|enterAlways"/>
    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:id="@+id/dashboard_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

И в каждом фрагменте, который вы не хотите реализовать app:layout_behavior="@string/appbar_scrolling_view_behavior", вам придется переопределить методы onAttach и onDetach, которые изменят поведение вашего FrameLayout:

CoordinatorLayout.Behavior behavior;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if(behavior != null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    behavior = params.getBehavior();
    params.setBehavior(null);

}

@Override
public void onDetach() {
    super.onDetach();
    if(behavior == null)
        return;

    FrameLayout layout =(FrameLayout) getActivity().findViewById(R.id.dashboard_content);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layout.getLayoutParams();

    params.setBehavior(behavior);

    layout.setLayoutParams(params);

    behavior = null;
}

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

Ответ 2

Здесь мое решение

<!-- Put your fragment inside a Framelayout and set the behavior for this FrameLayout -->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- Your fragment -->
    <include layout="@layout/content_main" />

</FrameLayout>

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

Ответ 3

Это очень хороший вопрос: должен ли Toolbar действовать как ActionBar в Activity или Fragment? Проанализировав различные вопросы и документацию, я не смог найти решение, которое охватывает все случаи. Поэтому это действительно зависит от вашей ситуации, в которой вы можете пойти.

Случай 1: Панель инструментов должна быть заменой ActionBar

Если панель инструментов должна вести себя как обычный ActionBar (или время макс. 1 фрагмент), я считаю, что лучший/самый простой способ - использовать традиционный Activities с собственной панелью инструментов и поместить ваш фрагмент в там. Таким образом, вам не нужно беспокоиться о том, когда должна отображаться панель инструментов.

Изменение ActionBar (-behaviour) из фрагментов также возможно, но я бы не рекомендовал его, так как это заставляет вас отслеживать, какой фрагмент изменил ActionBar, когда. Я даже не знаю, можно ли сделать ActionBar несколько раз.

Случай 2: у каждого фрагмента должна быть своя (часть) панели инструментов

Вы также можете поместить различные отдельные панели инструментов в разные фрагменты с их собственными действиями. Таким образом, вы можете отображать разные фрагменты рядом друг с другом - каждый со своими действиями на панели инструментов - и предположим, что это 1 панель инструментов (возможно, как приложение Gmail, хотя я не уверен). Это, однако, означает, что вам придется раздувать эти Панели инструментов самостоятельно, но это не должно быть очень сложно.

Надеюсь, это поможет сделать выбор.

(Извините, если я допустил любые (языковые) ошибки)