AppCompat v21 — Material Design для пре-Lollipop устройств
17 октября был опубликован Android 5.0 SDK, который принес новые виджеты и материальный дизайн. Мы расширили библиотеки поддержки, чтобы вы могли использовать ваши последние разработки и на предыдущих версиях Android. Это изменения включают в себ крупное обновление для AppCompat, а так же библиотеки RecyclerView, CardView и Palette.
В этом посте мы взглянем, что нового появилось в AppCompat и как это использовать для поддержки материального дизайна в ваших приложениях.
Что нового в AppCompat?
Библиотека AppCompat (aka ActionBarCompat) появилась как порт нового ActionBar API из Android 4.0 на устройства с Gingerbread. Она представила общий слой API поверх бэкпортированной либо стандартной реализации. AppCompat v21 же приносит API и набор возможностей из Android 5.0
В этой версии Android появился новый виджет Toolbar. Он представляет собой обобщение шаблона ActionBar и дает больше контроля и гибкости. Toolbar — это элемент view в общей иерархии, что упрощает реализацию его взаимодействия с другими виджетами, анимации и реакции на события прокрутки. Так же вы можете использовать его как Actionbar вашей активности, а это значит, что стандартные элементы меню действий будут показываться в нем.
Вы, вероятно, уже пользовались какое-то время обновленной версией AppCompat. Эта библиотека была включена в обновления различных программ Google, вышедшие в последние недели, в том числе Play Маркет и Play Пресса. Кроме того, он был интегрирован в приложение Google I/O, изображенное выше, которое имеет открытый исходный код.
Установка
Если вы используете Gradle, просто добавьте appcompat как зависимость в ваш файл build.gradle:
Новая интеграция
Если вы ещё не используете AppCompat или начинаете с нуля, вот как её подключить:
- Все ваши активности должны наследоваться от ActionBarActivity, которая в свою очередь наследуется от FragmentActivity из библиотеки v4 support, поэтому вы можете продолжать использовать фрагменты.
- Все вашим темы (которые включают Action Bar/Toolbar) должны наследоваться от Theme.AppCompat. Есть несколько вариантов тем, в том числе светлая (Light) и тема без панели действий (NoActionBar).
- Когда внедряете что-то для отображения в панели (например, SpinnerAdater для навигации), удостоверьтесь, что используете контекст с темой панели, полученный с помощью getSupportActionBar().getThemedContext().
- Вы должны использовать статические методы класса MenuItemCompat для вызовов MenuItem, относящимся к действиям.
Для получения дополнительной информации обратитесь к руководству по API Action Bar, которое является исчерпывающим руководством по AppCompat.
Миграция с предыдущих версий
Для большинства приложений теперь вам достаточно одного объявления темы в values/:
Теперь вы можете убрать все стили ActionBar из values-v14+.
Темы оформления
AppCompat поддерживает новые атрибуты цветовой палитры, которые позволяют настроить тему под ваш брэнд, используя основной и акцентный цвета. Например:
Когда вы зададите эти аттрибуты, AppCompat автоматически применит их как значения атрибутов из API 21+. А это, в свою очередь, окрасит панель статуса и элемент в списке недавних задач.
На более старых платформах, AppCompat эмулирует цветовые темы, когда это возможно. В текущий момент, это ограничивается окрашиванием панели действий и некоторыми виджетами.
Тонировка виджетов
Когда вы запускаете приложение на устройстве с Android 5.0, все виджеты тонируются цветом, указанным в атрибутах темы. Есть две основные возможности, которые позволяют это делать на Lollipop: тонировка drawable и ссылки на аттрибуты тем (в формате ?attr/foo) внутри drawable.
AppCompat предлагает похожее поведение на ранних версиях Android для следующего множества UI виджетов:
- Все, что предлагается в AppCompat toolbar (режимы действий и прочее)
- EditText
- Spinner
- CheckBox
- RadioButton
- Switch (используйте новый класс android.support.v7.widget.SwitchCompat)
- CheckedTextView
Вам ничего не нужно делать специально, чтобы это заработало. Используйте эти элементы в вашей разметке как обычно, а AppCompat сделает остальное (с некоторыми оговорками, см. FAQ ниже).
Виджет панели инструментов (Toolbar)
Action Bar
Чтобы использовать Toolbar в качестве ActionBar, во-первых, отключите обычный ActionBar. Самый простой способ сделать это — унаследовать вашу тему от Theme.AppCompat.NoActionBar (или светлого её варианта)
Во-вторых, создайте экземпляр панели инструментов. Например, включив её в ваш xml-файл разметки
Высота, ширина, фон и прочее теперь полностью зависят от вас, это просто хороший пример. Так как Toolbar — это просто ViewGourp, вы можете стилизовать и позиционировать его на своё усмотрение.
И наконец, установите Toolbar в качестве ActionBar в вашей активности или фрагменте:
Начиная с этого момента все элементы меню будут отображаться в вашей панели инструментов, наполняясь с помощью стандартных вызовов настройки меню.
Автономное использование
Отличие автономного режима в том, что вы не задаете Toolbar в качестве ActionBar. Поэтому, вы можете использовать любую тему AppCompat и вам не нужно отключать обычный ActionBar.
В автономном режиме вы можете наполнять Toolbar содержимым или действиями. Например, если вы хотите показать действия, вам нужно внедрить меню:
Есть множество других вещей, которые можно делать с панелью инструментов. Для получения дополнительной информации, смотрите описание Toolbar API.
Стили
Настройка стиля панели инструментов отличается от того, как это делалось для стандартной панели действий. Стиль применяется прямо к самому виджету.
Вот основной стиль, который вы должны использовать, когда вы используете Toolbar в качестве ActionBar:
Объявление app:theme позволит убедиться, что шрифт и элементы используют чистый цвет (например, 100% непрозрачный белый).
Темная панель действий
Вы можете настроить панель инструментов напрямую, используя атрибуты разметки. Чтобы Toolbar выглядела как «DarkActionBar» (тёмное содержимое, светлое меню переполнения), укажите атрибуты theme и popupTheme:
Виджет поиска (SearchView)
AppCompat предлагает обновленное API для виджета поиска, которое поддается большей настройке и стилизации. Теперь мы используем структуру стилей из Lollipop вместо старых searchView* аттрибутов темы.
Вот как вы можете настроить стиль SearchView:
Вам не нужно указывать все (или вообще какие-то) из аттрибутов. Значения по-умолчанию должны подойти большинству приложений.
Toolbar на подходе.
Надеюсь, эта статья поможет приступить к работе с AppCompat и позволит создать удивительные приложения в материальном стиле. Дайте знать в комментариях к оригинальной статье/Google+/Twitter, если у вас есть вопросы о AppCompat или о любой из поддерживаемых библиотек, или где мы можем предоставить больше документации
Почему мой EditText (или другой виджет из списка выше) не окрашен корректно на устройстве с Android до Lollipop?
Тонирование виджетов в AppCompat работает с помощью перехвата внедрения разметки и вставки специальных тонированных версий виджетов. Для большинства людей это будет работать правильно. Но есть несколько сценариев, когда это не работает, в том числе:
- У вас кастомизированная версия виджета (вы отнаследовали EditText)
- Вы создаете EditText без использования LayoutInflater (например, вызвав new EditText())
Специальные тонированные версии виджетов пока скрыты, так как они находятся в незаконченном состоянии. Это может измениться в будущем.
Почему виджет X не имеет материального стиля на не-Lollipop устройствах?
Пока были обновлены только некоторые, самые распространенные виджеты. В будущих релизах будут добавлены другие.
Почему у моего Action Bar осталась тень на Android Lollipop? Я задал android:windowContentOverlay равный null.
На Lollipop тень под панелью создается с помощью нового API подъема. Чтобы убрать её, вам нужно вызвать getSupportActionBar().setElevation(0) или задать значение атрибута elevation в описании стиля Actionbar.
Почему нет ripple-анимации на устройствах до Lollipop?
Главное, что позволяет RippleDrawable анимироваться плавно в Android 5.0 — это новый RenderThread. Для оптимизации производительности на предыдущих версиях Android мы пока оставили RippleDrawable за бортом.
Как мне использовать AppCompat с Preferences?
Вы можете продолжать использовать PreferenceFragment в ActionBarActivity, когда запускаете приложение на устройстве с API v11+. Для устройств с предыдущей версией API вам придется использовать PreferenceActivity, которая не стилизована под материальный дизайн.
Источник
Возникают ошибки в com.android.support:appcompat-v7:28.0.0 что делать?
до момента все работало нормально. приложение компилировалось . даже выложил на гугл плей.
что я сделал не так? в builde.gradle подчеркивает красным цветом implementation ‘com.android.support:appcompat-v7:28.0.0‘
при компиляции вылетает ошибка такая:
Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.graphics.drawable.IconCompatParcelizer found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.IResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.ResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.ResultReceiver$1 found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class androidx.core.graphics.drawable.IconCompatParcelizer found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class androidx.core.internal.package-info found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
Duplicate class androidx.versionedparcelable.CustomVersionedParcelable found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.NonParcelField found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.ParcelField found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.ParcelImpl found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.ParcelImpl$1 found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.ParcelUtils found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcel found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcel$1 found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcel$ParcelException found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelParcel found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelStream found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelStream$FieldBuffer found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelStream$InputBuffer found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelable found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Duplicate class androidx.versionedparcelable.VersionedParcelize found in modules classes.jar (androidx.versionedparcelable:versionedparcelable:1.0.0) and classes.jar (com.android.support:versionedparcelable:28.0.0)
Go to the documentation to learn how to Fix dependency resolution errors.
Источник