Свернуть панель инструментов Android, что это такое

Обновлено: 24.09.2022

CoordinatorLayout расширяет возможности реализации многих эффектов прокрутки Google Material Design. В настоящее время в этой структуре предусмотрено несколько способов, которые позволяют ей работать без необходимости писать собственный код анимации. Эти эффекты включают:

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

Примеры кода

Крис Бейнс из Google создал прекрасную демонстрацию CoordinatorLayout и других функций библиотеки поддержки дизайна.


Полный исходный код можно найти на github. Этот проект — один из самых простых способов понять CoordinatorLayout .

Настройка

Добавьте CoordinatorLayout в свой список зависимостей в app/build.gradle:

Плавающие кнопки действий и снэкбары

CoordinatorLayout можно использовать для создания плавающих эффектов с помощью атрибутов layout_anchor и layout_gravity. Дополнительные сведения см. в руководстве по плавающим кнопкам действий.

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

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

Развертывание и свертывание панелей инструментов

Первый шаг — убедиться, что вы не используете устаревшую панель действий. Обязательно следуйте руководству «Использование панели инструментов в качестве панели действий». Также убедитесь, что CoordinatorLayout является основным контейнером макета.

Ответ на события прокрутки

Затем мы должны настроить панель инструментов на события прокрутки, используя макет контейнера AppBarLayout:

Примечание. Согласно официальной документации Google, в настоящее время AppBarLayout должен быть прямым дочерним элементом, вложенным в CoordinatorLayout.

Далее нам нужно определить связь между AppBarLayout и представлением, которое будет прокручиваться. Добавьте app:layout_behavior в RecyclerView или любое другое представление, поддерживающее вложенную прокрутку, например NestedScrollView. Библиотека поддержки содержит специальный строковый ресурс @string/appbar_scrolling_view_behavior, который сопоставляется с AppBarLayout.ScrollingViewBehavior, который используется для уведомления AppBarLayout о возникновении событий прокрутки в этом конкретном представлении. Поведение должно быть установлено в представлении, которое запускает событие.

Когда CoordinatorLayout замечает этот атрибут, объявленный в RecyclerView, он будет искать среди других представлений, содержащихся в нем, любые связанные представления, связанные с поведением. В данном конкретном случае AppBarLayout.ScrollingViewBehavior описывает зависимость между RecyclerView и AppBarLayout. Любые события прокрутки в RecyclerView должны инициировать изменения макета AppBarLayout или любых представлений, содержащихся в нем.

События прокрутки в RecyclerView инициируют изменения внутри представлений, объявленных в AppBarLayout, с помощью атрибута app:layout_scrollFlags:

Флаг прокрутки, используемый в атрибуте app:layout_scrollFlags, должен быть включен, чтобы любые эффекты прокрутки вступили в силу. Этот флаг должен быть включен вместе с enterAlways , enterAlwaysCollapsed , exitUntilCollapsed или snap :

enterAlways: представление станет видимым при прокрутке вверх. Этот флаг полезен в тех случаях, когда прокручивается список снизу и требуется открыть панель инструментов, как только происходит прокрутка вверх.


Обычно панель инструментов появляется только при прокрутке списка вверх, как показано ниже:


enterAlwaysCollapsed : обычно, когда используется только enterAlways, панель инструментов будет продолжать расширяться при прокрутке вниз:


Предположим, что enterAlways объявлен и вы указали minHeight, вы также можете указать enterAlwaysCollapsed. Когда используется этот параметр, ваш вид будет отображаться только на этой минимальной высоте. Только когда прокрутка достигает верха, вид расширяется до полной высоты:


exitUntilCollapsed : если установлен флаг прокрутки, прокрутка вниз обычно приводит к перемещению всего содержимого:

Указав minHeight и exitUntilCollapsed , минимальная высота панели инструментов будет достигнута до того, как остальной контент начнет прокручиваться и исчезнет с экрана:



snap : использование этого параметра определяет, что делать, если представление уменьшено лишь частично. Если прокрутка заканчивается и размер представления уменьшился менее чем на 50% от исходного, то это представление вернется к исходному размеру. Если размер превышает 50% от его размера, он полностью исчезнет.

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

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

Создание эффектов свертывания

Если мы хотим создать эффект сворачивания панели инструментов, мы должны обернуть панель инструментов внутри CollapsingToolbarLayout:

Теперь ваш результат должен выглядеть так:

Обычно мы устанавливаем заголовок панели инструментов. Теперь нам нужно установить заголовок на CollapsingToolBarLayout вместо панели инструментов.

Обратите внимание, что при использовании CollapsingToolbarLayout строка состояния должна быть полупрозрачной (API 19) или прозрачной (API 21), как показано в этом файле. В частности, в файле res/values-xx/styles.xml должны быть установлены следующие стили, как показано на рисунке:

Включив полупрозрачные системные панели, как показано выше, ваш макет заполнит область за системными панелями, поэтому вы также должны включить android:fitsSystemWindow для тех частей макета, которые не должны быть закрыты системными панелями. Дополнительный обходной путь для API 19, который добавляет отступы, чтобы избежать обрезки представлений в строке состояния, можно найти здесь.

Создание анимации параллакса

CollapsingToolbarLayout также позволяет выполнять более сложные анимации, например использовать ImageView, который исчезает при сворачивании. Высота заголовка также может меняться по мере прокрутки пользователем.

Чтобы создать этот эффект, мы добавляем ImageView и объявляем атрибут app:layout_collapseMode="parallax" в теге.

Нижние листы

Нижние листы изначально поддерживаются в AndroidX. Поддерживаются два типа нижних листов: постоянные и модальные. На постоянных нижних листах отображается содержимое приложения, а на модальных листах отображаются меню или простые диалоговые окна.


Постоянные модальные листы

Существует два способа создания постоянных модальных листов. Первый способ — использовать NestedScrollView и просто встроить содержимое в это представление. Второй способ — создать их с помощью дополнительного RecyclerView, вложенного в CoordinatorLayout. Этот RecyclerView будет скрыт по умолчанию, если заданное layout_behavior установлено с использованием предопределенного значения @string/bottom_sheet_behavior. Также обратите внимание, что этот RecyclerView должен использовать wrap_content вместо match_parent , что является новым изменением, позволяющим нижнему листу занимать только необходимое пространство, а не всю страницу:

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

Далее мы создаем наш адаптер:

Нижний лист должен быть скрыт по умолчанию. Нам нужно использовать событие щелчка, чтобы вызвать отображение и скрытие. Примечание. Не пытайтесь расширить нижний лист внутри метода OnCreate() из-за этой известной проблемы.

Вы можете установить атрибут макета app:behavior_hideable=true, чтобы пользователь также мог смахивать нижний лист. Существуют и другие состояния, включая STATE_DRAGGING, STATE_SETTLING и STATE_HIDDEN. Для дополнительного чтения вы можете посмотреть еще один учебник по нижним листам здесь.

Модальные листы

Модальные листы в основном представляют собой фрагменты диалоговых окон, которые выдвигаются снизу. См. это руководство о том, как создавать такие типы фрагментов. Вместо того, чтобы расширяться от DialogFragment, вы должны расширяться от BottomSheetDialogFragment.

Расширенные примеры нижнего листа

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

Следующие руководства и примеры кода должны помочь в достижении этих более сложных эффектов:

  • Пример CustomBottomSheetBehavior — демонстрирует фазовые сдвиги с тремя состояниями во время прокрутки нижнего листа. Обратитесь к соответствующему сообщению stackoverflow для объяснения.
  • Учебное пособие Grafixartist Bottom Sheet: руководство по размещению и анимации плавающей кнопки действия при прокрутке нижнего листа.
  • Вы можете прочитать этот пост stackoverflow для дополнительного обсуждения того, как имитировать изменения состояния карт Google во время прокрутки.

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

Сторонние альтернативы нижнего листа

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

Следующее представляет наиболее распространенные альтернативы и соответствующие примеры:

  • AndroidSlidingUpPanel – сторонний подход к нижнему листу, который можно рассматривать как альтернативу официальному подходу. Поддерживает AndroidX.
  • Флипборд/нижний лист. Еще одна очень популярная альтернатива официальному нижнему листу, которая широко использовалась до того, как было выпущено официальное решение. Обратите внимание, что эта библиотека не поддерживает AndroidX и использует старую библиотеку поддержки.
  • ThreePhasesBottomSheet – пример кода, использующего сторонние библиотеки для создания многоэтапного нижнего листа.
  • Учебное пособие по Foursquare BottomSheet. Описывается, как использовать сторонние нижние листы для достижения эффекта, используемого в старой версии Foursquare.

Между официальными постоянными модальными листами и этими сторонними альтернативами вы должны быть в состоянии достичь любого желаемого эффекта при достаточном экспериментировании.

Устранение неполадок с согласованными макетами

CoordinatorLayout очень мощен, но поначалу подвержен ошибкам. Если у вас возникли проблемы с координацией поведения, воспользуйтесь следующими советами ниже:

  • Лучший пример того, как эффективно использовать макет координатора, — это внимательное обращение к исходному коду Cheesesquare. Этот репозиторий представляет собой образец репозитория, который Google постоянно обновляет, чтобы отразить лучшие практики координации поведения. В частности, см. макет для списка ViewPager с вкладками и макет для подробного представления. Внимательно сравните свой код с исходным кодом cheesesquare.
  • Убедитесь, что свойство app:layout_behavior="@string/appbar_scrolling_view_behavior" применяется к прямому дочернему объекту CoordinatorLayout . Например, при обновлении по запросу свойство применяется к SwipeRefreshLayout, содержащему RecyclerView, а не потомку 2-го уровня.
  • При координации между фрагментом со списком элементов внутри ViewPager и родительской активностью вы хотите поместить свойство app:layout_behavior в ViewPager, как описано здесь, чтобы прокрутки внутри пейджера всплывали и ими можно было управлять. КоординаторLayout . Обратите внимание, что вы не должны размещать это свойство app:layout_behavior где-либо внутри фрагмента или списка внутри.
  • Имейте в виду, что ScrollView не работает с CoordinatorLayout . Вместо этого вам нужно будет использовать NestedScrollView, как показано в этом примере. Оборачивая содержимое в NestedScrollView и применяя свойство app:layout_behavior, поведение прокрутки будет работать должным образом.
  • Убедитесь, что корневой макет вашего действия или фрагмента является CoordinatorLayout . Прокрутки не будут реагировать ни на какие другие макеты.

Существует множество причин, по которым согласование макетов может пойти не так. Добавляйте сюда советы по мере их обнаружения.

Пользовательские варианты поведения

Один пример пользовательского поведения обсуждается при использовании CoordinatorLayout с плавающими кнопками действий.

CoordinatorLayout работает путем поиска в любом дочернем представлении, в котором поведение CoordinatorLayout Behavior определено либо статически как XML с тегом app:layout_behavior, либо программно с помощью класса View, аннотированного декоратором @DefaultBehavior. Когда происходит событие прокрутки, CoordinatorLayout пытается инициировать другие дочерние представления, объявленные как зависимости.

Чтобы определить собственное поведение CoordinatorLayout, необходимо реализовать layoutDependsOn() и onDependentViewChanged(). Например, в AppBarLayout.Behavior определены эти два ключевых метода. Это поведение используется для запуска изменения в AppBarLayout при возникновении события прокрутки.

Лучший способ понять, как реализовать эти настраиваемые поведения, — это изучить исходные коды AppBarLayout.Behavior и FloatingActionButtion.Behavior.

Сторонняя прокрутка и параллакс

Помимо использования CoordinatorLayout, как описано выше, обязательно ознакомьтесь с этими популярными сторонними библиотеками для эффектов прокрутки и параллакса в ScrollView , ListView , ViewPager и RecyclerView .

Встраивание Карт Google в AppBarLayout

В настоящее время нет возможности поддерживать фрагмент Google Maps в AppBarLayout, как подтверждается в этой проблеме. Изменения в библиотеке дизайна поддержки версии 23.1.0 теперь предоставляют метод setOnDragListener(), который полезен, если в этом макете необходимы эффекты перетаскивания. Однако, похоже, это не влияет на прокрутку, как указано в этой статье блога.

фон Android

Недавно перед Mindgrub была поставлена ​​задача внедрить представление профиля пользователя в приложение для Android. Этот вид профиля будет заполнять верхнюю часть экрана изображением профиля, а затем сворачиваться в «обычную» панель инструментов при прокрутке вниз экрана.

Вот пример:

Изначально я беспокоился, что нам придется найти стороннюю библиотеку, в которой реализована эта сворачивающаяся панель инструментов (или написать ее самому). К счастью, Google только что выпустил библиотеку поддержки дизайна Android, и подобную анимацию можно создавать с помощью новых виджетов, представленных в этой библиотеке.

Вот код очень простой демонстрации этого поведения:

Просто, правда? Ну, может быть, не с первого взгляда — но это не так уж сложно понять, если разобрать. Давайте проанализируем каждый элемент XML по частям:

МАКЕТ КООРДИНАТОРА

Это должен быть элемент верхнего уровня в вашем фрагменте или действии. CoordinatorLayout — это новый тип элемента, представленный в библиотеке дизайна — в основном он «координирует» поведение между его дочерними представлениями. Поведение определяется атрибутами, установленными в его дочерних представлениях, которые относятся к макету координатора.

ПРИЛОЖЕНИЕ

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

На самом деле AppBarLayouts должны быть дочерними элементами CoordinatorLayouts, а также должны иметь одноуровневый элемент с атрибутом layout_behavior, для которого установлено значение AppBarLayout.ScrollingViewBehavior. Установка этого атрибута в родственном элементе привязывает этот элемент к AppBarLayout, что позволяет ему знать, когда следует прокручивать. Мы привязываем AppBarLayout к NestedScrollView, что обсуждается ниже.

Свернуть макет панели инструментов

Этот элемент является дочерним элементом "AppBarLayout" и объявляет желаемое поведение "Свертывания". Дочерние элементы этого элемента объявят, как сворачивается панель инструментов.

ПРОСМОТР ИЗОБРАЖЕНИЯ

Только обычный ImageView, за некоторыми исключениями: мы устанавливаем для параметра «layout_collapseMode» значение «parallax», что приводит к тому, что ImageView перемещается при прокрутке пользователем в определенном соотношении. Вы можете установить это соотношение с помощью (необязательной) настройки «layout_collapseParallaxMultiplier».

ПАНЕЛЬ ИНСТРУМЕНТОВ

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

ВКЛАДАННАЯ ПРОКРУТКА

Это родственный элемент для «AppBarLayout», упомянутого выше. Это просто обычный NestedScrollView, за исключением набора атрибутов «layout_behavior». Как упоминалось выше, установка этого атрибута привязывает его к родственному элементу AppBarLayout.

ТЕКСТ

Это просто прокручиваемый контент. Это не обязательно должен быть TextView — это может быть любой вид макета, recyclerview и т. д. Здесь я использовал TextView для простоты.

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


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

Мы увидели, что Coordinator Layout является центральной точкой, от которой зависят другие компоненты для правильной работы, и что AppBarLayout помогает панели инструментов и другим компонентам реагировать на изменения прокрутки. Сегодня я покажу вам, как использовать сворачивающийся макет панели инструментов для очень простого создания потрясающих эффектов.

Если вы помните, я менял код своего репозитория MaterializeYourApp, чтобы начать использовать библиотеку поддержки дизайна. Сегодня я изменю экран детализации, и мы получим что-то вроде этого:

Добавить макет координатора

Это первое, что вам нужно. Во всех новых компонентах используется новая концепция под названием «Поведение», которая используется макетом координатора для выполнения некоторых действий на основе различных взаимодействий.

Мы будем использовать fitsSystemWindows для любого элемента, который мы хотим отобразить под строкой состояния.

Добавить макет панели приложений

Здесь тоже ничего сложного. Мы устанавливаем темную тему для AppBarLayout , поэтому нам не нужно указывать каждому дочернему элементу, что он должен использовать темную тему.

Это основная часть этой статьи.Во-первых, сворачивающийся макет указывает, как он будет вести себя при прокрутке содержимого с помощью флагов scroll|exitUntilCollapsed, поэтому он будет прокручиваться до тех пор, пока полностью не свернется. Затем мы указываем contentScrim — цвет, который примет панель инструментов, когда она достигнет свернутого состояния. Я изменю это программно и использую палитру, чтобы определить его цвет. Мы также можем указать поля для заголовка, когда он развернут. Это создаст приятный эффект над заголовком панели инструментов. Вы можете определить некоторые другие вещи, такие как statusScrim или textAppearance для свернутого и развернутого заголовка.

Внутри макета я добавил изображение с режимом свертывания параллакса и панель инструментов, которая использует режим закрепления панели инструментов (она будет оставаться на своем месте).

Добавить представление вложенной прокрутки

Остальная часть XML просто состоит из добавления NestedScrollView . Это специальное представление с прокруткой, которое может находиться внутри другой ViewGroup с прокруткой. Таким образом, мы можем видеть непрерывность при прокрутке.

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

Привязка плавающей кнопки действия

Мы можем использовать CoordinatorLayout для привязки одних представлений к другим. Это чрезвычайно полезная функция. Кроме того, поведение FloatingActionButton также будет обращать внимание на изменения AppBarLayout и будет скрываться при сворачивании. Итак, еще один приятный эффект бесплатно:

Больше ничего не нужно. Вы можете увидеть полный XML на Github.

Некоторые настройки кода

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

О последнем важно знать, что мы не можем использовать изображение в качестве цели перехода. Почему-то не получится. Попробовав несколько разных вариантов, я обнаружил, что лучше всего работает с AppBarLayout :

[java]
ViewCompat.setTransitionName(findViewById(R.id.app_bar_layout), EXTRA_IMAGE);
[/java]

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

[java]
collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbarLayout.setTitle(itemTitle);
collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));
[/java]

Я также подкрашиваю панель инструментов и FAB с помощью Palette. Я не буду вдаваться в подробности об этом, но вы можете проверить код для получения более подробной информации:

[java]
collapsingToolbarLayout.setContentScrimColor(palette.getMutedColor(основной));
collapsingToolbarLayout.setStatusBarScrimColor(palette.getDarkMutedColor(primaryDark));

fab.setRippleColor(lightVibrantColor);
fab.setBackgroundTintList(ColorStateList.valueOf(vibrantColor));
[/java]

Заключение

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

введите здесь описание изображения

Это мой фрагмент кода, который я реализовал


У вас есть .setTitle(" "); . Я предполагаю, что вы хотели .setTitle("Математика")? В противном случае да, ваша панель инструментов пуста - это ваша проблема? Этот пример кода, на который вы ссылаетесь, также обрабатывает круглое изображение.

вам просто нужно установить заголовок как collapsingToolbarLayout.setTitle("YOUR TITLE"); и при прокрутке заголовок автоматически переместится на панель инструментов

Я хотел, чтобы представление изображения выравнивалось справа от кнопки "Назад", а текстовое представление содержало математику, которая должна выравниваться справа от представления изображения, когда панель инструментов сворачивается. Я пытался выполнить код CoordinatorBehaviourExample, но не смог добиться желаемого результата.

4 ответа 4

Я предварительно прочитал два потрясающих демонстрационных примера сворачивания аватара с подходом, который не использует пользовательский CoordinatorLayoutBehavior !

демонстрация 1 демонстрация 2

Вместо использования пользовательского CoordinatorLayoutBehavior я использую OnOffsetChangedListener из AppBarLayout .

Демонстрация 1

в методе updateViews аватар изменяет размер и изменяет положение аватара по осям X, Y в первой демонстрации.

чтобы найти avatarAnimateStartPointY и avatarCollapseAnimationChangeWeight (для преобразования общего смещения в смещение анимации аватара):

Демонстрация 2

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

Вам необходимо отслеживать состояния: изменение TO_EXPANDED_STATE, изменение TO_COLLAPSED_STATE, WAIT_FOR_SWITCH .

Создать анимацию для аватара при изменении состояния:


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

Вот еще один подход, в котором не используется пользовательский CoordinatorLayoutBehavior .

Он использует OnOffsetChangedListener из AppBarLayout .

Вот фрагмент:

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

Мне этот подход показался немного проще, чем создание пользовательского поведения.

Читайте также: