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

94

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

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

mobilepotato7
источник
1
Привет, ты нашел решение?
SERG
2
в моем текущем проекте я решил придерживаться панели инструментов в Activity и при необходимости делать правильную анимацию. Но это немного запутано. Я пробовал использовать панель инструментов в каждом фрагменте, и она работает нормально, но анимировать панель инструментов между переходами фрагментов сложнее, и я даже не знаю, возможно ли это, потому что у меня нет большого опыта работы с анимацией переходов фрагментов.
mobilepotato7
какие-нибудь обновления или лучшие решения для этого сейчас?
Сагар Наяк

Ответы:

56

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

Чтобы решить эту проблему с помощью 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 не будет сворачивать панель приложений и т. Д. И позволит макетам фрагментов быть во всю высоту.

Клаус Шварц
источник
Хороший, придется попробовать это и посмотреть, упростит ли это ситуацию. Спасибо.
mobilepotato7
Если найдете что-то попроще - дайте мне знать. Я думаю, что можно изменить поведение координатора в любой момент в течение жизненного цикла фрагментов (например, у вас обычно есть переработчик с некоторыми вещами, но в редких случаях он может быть пустым, и вы узнаете, что только после загрузчика onLoadFinished, возможно, вы нравится показывать центрированное изображение, уведомляющее, что здесь ничего нет, как в приложении Inbox), но я еще не пробовал этого. Может быть, сегодня позже.
Клаус Шварц
Хорошо, это работает очень хорошо. Я создал помощника, который заботится о включении / отключении координатора, когда это необходимо, поэтому я просто вызываю enableCoordinator(Activity activity)/ disableCoordinator(Activity activity)из фрагментов.
Клаус Шварц
Где твой помощник, @ КлаусШварц? Когда вы это называете?
Сантьяго,
1
@santhyago Во фрагменте
Клаус Шварц
8

Вот мое решение

<!-- 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>

Шарль-Эжен Лубао
источник
1

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

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

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

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

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

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

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

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

Коэн Б
источник
4
извините, но это не совсем решает проблемы, связанные с новой библиотекой дизайна. Конечно, целью является использование панели инструментов в качестве панели действий, но наличие нескольких макетов координатора для разных типов панелей инструментов может быть непростой задачей. Я обнаружил, что панель инструментов можно анимировать по мере необходимости. Мне все еще нужно проверить это лучше, но, похоже, есть хорошие результаты
mobilepotato7