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:
dependencies {
compile "com.android.support:appcompat-v7:21.0.+"
}
Новая интеграция
Если вы ещё не используете AppCompat или начинаете с нуля, вот как её подключить:
- Все ваши активности должны наследоваться от ActionBarActivity, которая в свою очередь наследуется от FragmentActivity из библиотеки v4 support, поэтому вы можете продолжать использовать фрагменты.
- Все вашим темы (которые включают Action Bar/Toolbar) должны наследоваться от Theme.AppCompat. Есть несколько вариантов тем, в том числе светлая (Light) и тема без панели действий (NoActionBar).
- Когда внедряете что-то для отображения в панели (например, SpinnerAdater для навигации), удостоверьтесь, что используете контекст с темой панели, полученный с помощью getSupportActionBar().getThemedContext().
- Вы должны использовать статические методы класса MenuItemCompat для вызовов MenuItem, относящимся к действиям.
Для получения дополнительной информации обратитесь к руководству по API Action Bar, которое является исчерпывающим руководством по AppCompat.
Миграция с предыдущих версий
Для большинства приложений теперь вам достаточно одного объявления темы в values/:
values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
<!-- Set AppCompat’s actionBarStyle -->
<item name="actionBarStyle">@style/MyActionBarStyle</item>
<!-- Set AppCompat’s color theming attrs -->
<item name="colorPrimary">@color/my_awesome_red</item>
<item name="colorPrimaryDark">@color/my_awesome_darker_red</item>
<!-- The rest of your attributes -->
</style>
Теперь вы можете убрать все стили ActionBar из values-v14+.
Темы оформления
AppCompat поддерживает новые атрибуты цветовой палитры, которые позволяют настроить тему под ваш брэнд, используя основной и акцентный цвета. Например:
values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/my_awesome_color</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">@color/my_awesome_darker_color</item>
<!-- colorAccent is used as the default value for colorControlActivated,
which is used to tint widgets -->
<item name="colorAccent">@color/accent</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight, and colorSwitchThumbNormal. -->
</style>
Когда вы зададите эти аттрибуты, 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)
Toolbar полностью поддерживается библиотекой AppCompat и полностью полностью соответствует как по возможностям, так и по API вызовам, виджету из SDK. В AppCompat, панель инструментов реализуется с помощью класса android.support.v7.widget.Toolbar. Есть два способа её применения:
- Использовать как ActionBar, если вы хотите использовать существующие возможности Action Bar (такие, как внедрение меню, выделение, ActionBarDrawerToggle и т.д.), но при этом хотите больше контроля над её внешним видом.
- Использовать автономную панель в ситуациях, когда обычный ActionBar не подходит. Например, чтобы показать несколько панелей на экране, занять только часть экрана по ширине и т.д.
Action Bar
Чтобы использовать Toolbar в качестве ActionBar, во-первых, отключите обычный ActionBar. Самый простой способ сделать это — унаследовать вашу тему от Theme.AppCompat.NoActionBar (или светлого её варианта)
Во-вторых, создайте экземпляр панели инструментов. Например, включив её в ваш xml-файл разметки
<android.support.v7.widget.Toolbar
android:id="@+id/my_awesome_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
Высота, ширина, фон и прочее теперь полностью зависят от вас, это просто хороший пример. Так как Toolbar — это просто ViewGourp, вы можете стилизовать и позиционировать его на своё усмотрение.
И наконец, установите Toolbar в качестве ActionBar в вашей активности или фрагменте:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
}
Начиная с этого момента все элементы меню будут отображаться в вашей панели инструментов, наполняясь с помощью стандартных вызовов настройки меню.
Автономное использование
Отличие автономного режима в том, что вы не задаете Toolbar в качестве ActionBar. Поэтому, вы можете использовать любую тему AppCompat и вам не нужно отключать обычный ActionBar.
В автономном режиме вы можете наполнять Toolbar содержимым или действиями. Например, если вы хотите показать действия, вам нужно внедрить меню:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
// Set an OnMenuItemClickListener to handle menu item clicks
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// Handle the menu item
return true;
}
});
// Inflate a menu to be displayed in the toolbar
toolbar.inflateMenu(R.menu.your_toolbar_menu);
}
Есть множество других вещей, которые можно делать с панелью инструментов. Для получения дополнительной информации, смотрите описание Toolbar API.
Стили
Настройка стиля панели инструментов отличается от того, как это делалось для стандартной панели действий. Стиль применяется прямо к самому виджету.
Вот основной стиль, который вы должны использовать, когда вы используете Toolbar в качестве ActionBar:
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
Объявление app:theme позволит убедиться, что шрифт и элементы используют чистый цвет (например, 100% непрозрачный белый).
Темная панель действий
Вы можете настроить панель инструментов напрямую, используя атрибуты разметки. Чтобы Toolbar выглядела как «DarkActionBar» (тёмное содержимое, светлое меню переполнения), укажите атрибуты theme и popupTheme:
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="@dimen/triple_height_toolbar"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
Виджет поиска (SearchView)
AppCompat предлагает обновленное API для виджета поиска, которое поддается большей настройке и стилизации. Теперь мы используем структуру стилей из Lollipop вместо старых searchView* аттрибутов темы.
Вот как вы можете настроить стиль SearchView:
values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat">
<item name="searchViewStyle">@style/MySearchViewStyle</item>
</style>
<style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView">
<!-- Background for the search query section (e.g. EditText) -->
<item name="queryBackground">...</item>
<!-- Background for the actions section (e.g. voice, submit) -->
<item name="submitBackground">...</item>
<!-- Close button icon -->
<item name="closeIcon">...</item>
<!-- Search button icon -->
<item name="searchIcon">...</item>
<!-- Go/commit button icon -->
<item name="goIcon">...</item>
<!-- Voice search button icon -->
<item name="voiceIcon">...</item>
<!-- Commit icon shown in the query suggestion row -->
<item name="commitIcon">...</item>
<!-- Layout for query suggestion rows -->
<item name="suggestionRowLayout">...</item>
</style>
Вам не нужно указывать все (или вообще какие-то) из аттрибутов. Значения по-умолчанию должны подойти большинству приложений.
Toolbar на подходе...
Надеюсь, эта статья поможет приступить к работе с AppCompat и позволит создать удивительные приложения в материальном стиле. Дайте знать в комментариях к оригинальной статье/Google+/Twitter, если у вас есть вопросы о AppCompat или о любой из поддерживаемых библиотек, или где мы можем предоставить больше документации
FAQ
Почему мой 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, которая не стилизована под материальный дизайн.
P.S. Это мой первый перевод, прошу писать в личку обо всех неточностях (особенно, что касается русских терминов)
Автор: Tishka17