ActionBar (Панель действий)
3-й курс/Закрытая зона
Немного теории
Начиная с Android 3.0 (API 11), в приложениях появилась возможность использовать панель действий ActionBar, которая сочетает в себе заголовок и меню, упрощая навигацию и предоставляя быстрый доступ к частым операциям.
ActionBar заменяет Options Menu, которое было в ранних версиях Android, используя новые дополнительные параметры для меню. По умолчанию, новые проекты, создаваемые через шаблоны Empty Activity и др., уже содержат ActionBar. Следует отметить, что в Android 5.0 появился новый компонент Toolbar, который является дальнейшим развитием ActionBar. И он активно вытесняет панель действий. Но вам всё равно следует изучить работу ActionBar, так как основные принципы работы завязаны на ней.
Если запустить программу как есть из шаблона Empty Activity, то увидим заголовок программы.
Если в код программы добавить методы для меню, то справа появится значок из трёх вертикальных точек.
Если щёлкнуть по значку из трёх точек, выстроенных по вертикали, то увидим всплывающее меню с единственным пунктом Settings. Не прикладывая никаких усилий, мы получили готовый элемент ActionBar в своём приложении.
Давайте разбираться, что происходит за кулисами приложения. За появление панели действий отвечает тема Theme.Holo или её производные. В API 21 и выше произошли небольшие изменения. Как я уже сказал выше, появился новый компонент ToolBar, который может заменить панель действий в активности. Поэтому тут нужно быть внимательным и выбирать соответствующую тему, например, Theme.Material.Light.DarkActionBar. Для старых устройств используются библиотеки совместимости. В этом случае активность наследуется от AppCompatActivity, а используемая тема Theme.AppCompat или его производные, например, Theme.AppCompat.Light.DarkActionBar.
В студии версии 4.1 снова всё поменяли и теперь используется тема Theme.MaterialComponents.DayNight.DarkActionBar.
Прячем и показываем ActionBar
Изначально существовали два вида ActionBar для новых устройств и для старых устройств при помощи библиотеки совместимости. Не смешивайте вызовы методов из разных классов, а то получите ошибку. На сегодняшний день студия создаёт проекты с применением библиотеки AndroidX, поэтому будем использовать классы из неё.
Чтобы увидеть разницу в активности с ActionBar и без неё, напишем простой пример. Добавим на форму компонент ToggleButton и пропишем код, скрывающий и показывающий ActionBar:
Вы вошли на сайт, как гость.
Необходимо зарегистрироваться, чтобы прочитать статью
Источник
Полный список
— используем навигацию в ActionBar
На прошлом уроке мы рассмотрели добавление элементов ActionBar. Пользователю эти элементы удобно использовать для совершения каких-либо операций в приложении. Например, в почтовой программе это может быть удаление письма, пересылка, ответ и т.д.
Теперь рассмотрим, как добавить элементы для навигации по приложению. Есть два типа элементов для навигации: табы и выпадающий список. Создадим простое приложение и реализуем в нем сначала один, затем второй способ.
Project name: P1081_ActionBarNavigation
Build Target: Android 4.1
Application name: ActionBarItems
Package name: ru.startandroid.develop.p1081actionbarnavigation
Create Activity: MainActivity
Никакие строки не добавляем, основной layout не трогаем.
Смотрим, что нам нужно, чтобы включить табы.
В onCreate мы получаем доступ к ActionBar и устанавливаем для него режим навигации в NAVIGATION_MODE_TABS. Далее идет добавление табов. Тут все несложно – создаем, пишем текст, присваиваем обработчика, добавляем в ActionBar.
Обработчиком для табов мы сделали MainActivity, оно реализует методы интерфейса ActionBar.TabListener:
onTabReselected – выбран уже выбранный таб
В эти методы поместим запись в лог и посмотрим, как оно все там работает.
Все сохраняем и запускаем приложение.
Сейчас выбран первый таб и лог сразу об этом сообщает:
selected tab: tab1
Нажмем на второй таб,
unselected tab: tab1
selected tab: tab2
Первый таб «развыбран», а второй выбран.
Еще раз нажмем на второй таб:
reselected tab: tab2
Второй таб перевыбран. Все логично и понятно.
Я, чтобы не перегружать урок, не стал реализовывать какие-либо операции по навигации в приложении. А, вообще, подразумевается, что в методах обработчика мы кодим операции с фрагментами. Нам даже любезно предоставляют объект FragmentTransaction для этих целей. При этом хелп предупреждает, что в этих методах нам не надо самим вызывать метод commit, а также мы не можем добавлять транзакцию в BackStack.
Выпадающий список
Теперь посмотрим, как работает навигация с выпадающим списком.
В onCreate получаем ActionBar и включаем ему режим навигации NAVIGATION_MODE_LIST. Для выпадающего списка необходимо создать адаптер, реализующий SpinnerAdapter. Пусть это будет ArrayAdapter. При создании используем массив из трех строк. Далее вызываем метод setListNavigationCallbacks, в который передаем адаптер и обработчик.
Обработчиком у нас снова является Activity, реализует метод onNavigationItemSelected интерфейса ActionBar.OnNavigationListener. Этот метод дает нам позицию и id выбранного из списка элемента. Выводим в лог эту инфу и соответствующий элемент массива.
В манифесте я прописал для MainActivity атрибут темы: android:theme=»@android:style/Theme.Holo.Light». Иначе был темный текст на темном фоне.
Все сохраняем и запускаем.
Первый элемент сразу выбран. В логах видим:
selected: position = 0, one
Выберем какой-нить другой элемент из списка
selected: position = 2, three
Снова все логично и понятно.
Для обоих видов навигации мы всегда можем получить текущий выбранный элемент с помощью метода getSelectedNavigationIndex. А для навигации с табами есть также метод getSelectedTab, возвращающий текущий выбранный таб.
Разумеется, что вместе с навигацией мы можем добавлять в ActionBar и обычные элементы, которые были рассмотрены на прошлом уроке.
При этом, если места будет недостаточно, то ActionBar разделит все свои элементы на две полосы.
Начиная с четвертой версии Андроид, можно использовать атрибут uiOptions для Activity или Application в манифесте. Если присвоить ему значение splitActionBarWhenNarrow, то результат при нехватке места получится такой:
Элементы ушли вниз. Правда, при этом почему-то перестает работать withText в showAsAction.
На следующем уроке:
— работаем с ListFragment
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
ActionBar на Android 2.1+ с помощью SupportLibrary
Недавно я писал о том, что Google добавил поддержку ActionBar в свою Support Library. Думаю, стоит рассказать, как же им пользоваться. Под катом — инструкция по правильному импорту библиотеки в свой проект и основные моменты использования SupportActionBar.
Импорт библиотеки
Чтобы наш ActionBar был виден на старых устройствах, нужно наследовать тему приложения от Theme.AppCompat. Сама собой она ниоткуда не возьмётся, поэтому нужно создать проект библиотеки (оригинальная инструкция на английском для Eclipse и Android Studio здесь(смотреть пункт Adding libraries with resources)):
1. Сначала нужно убедиться, что у нас закачана последняя версия Support Library. Для этого открываем SDK Manager и листаем в самый низ, до папки Extras. В ней есть пункт Android Support Library – он то нам и нужен. Обновляем его до последней версии (сейчас – rev. 18), если не сделали этого раньше.
2. Обновили? Молодцы. Теперь нажимаем File > New > В папке Android выбираем Android Project from existing code.
3. Нажимаем кнопку Browse… и ищем нужную нам папку. Путь до неё примерно такой: /extras/android/support/v7/appcompat/. Выделяем появившийся пункт в списке и нажимаем Finish.
4. Теперь у вас в Project Explorer должен появиться проект android-support-v7-appcompat. Открываем его, в папке libs/ на обеих .jar – файлах кликаем правой кнопкой и нажимаем Build Path > Add to Build Path.
5. Щелчок правой кнопкой мыши по проекту, выбираем Build Path > Configure Build Path.
6. На странице Build Path во вкладке Order and Export отмечаем два только что добавленных .jar – файла и снимаем отметку с Android Dependencies.
7. Нажимаем ОК для сохранения изменений. Всё – библиотека готова к использованию!
Создание приложения
Теперь создадим проект своего приложения, которое мы и будем делать. Имя – SupportActionBarDemo, пакет – com.habrahabr.sabd, минимальный API level 7 (таковы требования библиотеки). Создаём Activity, имя – MainActivity, layout – main.
Теперь кликаем правой кнопкой мыши по этому проекту и нажимаем Properties. На странице Android под заголовком Library нажимаем Add и выбираем в появившемся окне android-support-v7-appcompat, затем – ОК и ещё раз ОК, чтобы сохранить изменения. Теперь библиотека добавлена в проект!
Простой пример
Прежде всего идём в res/values/styles.xml, res/values-v11/styles.xml, res/values-v14/styles.xml (спасибо DeusModus)и пишем
Теперь ActionBar будет виден на любых версиях андроида.
Открываем res/values/strings.xml и добавляем строки:
Открываем res/menus/main.xml и пишем там:
Обратите внимание на атрибуты xmlns:sabd=«schemas.android.com/apk/res-auto» и sabd:showAsAction – без них ActionBar будет неправильно работать. Иконки случайные, значения не имеют. Я всё-таки напишу, что означает атрибут sabd:showAsAction:
always — элемент всегда будет виден, если места не хватает, заголовок будет показан не полностью
ifRoom — элемент будет виден, только если для него есть место
never — элемент никогда не будет виден, для его показа нужно нажать кнопку Меню на устройстве или кнопку Overflow на ActionBar при отсутствии первой
withText -элемент будет показываться только с его заголовком
collapseActionView — элемент может сворачиваться в кнопку или разворачиваться на всю ширину Actionbar по нажатию, далее я приведу его пример
Теперь приступаем непосредственно к написанию кода. Первым делом в коде Activity нужно заменить extends Activity на extends ActionBarActivity и добавить её в импорт. В последних версиях ADT при создании Activity автоматически создаётся метод onCreateOptionsMenu(Menu menu), в котором мы и создаём меню:
Запускаем приложение и видим наш ActionBar:
Item 2 не отобразился, так как для него не хватило места. Item 3 ни при каких условиях не будет виден, потому что мы выставили атрибут sabd:showAsAction=«never». Добраться до них можно с помощью кнопки «Меню» на устройстве.
Обрабатывать нажатия на элементы меню можно там же, где и раньше — в методе onOptionsItemSelected(MenuItem item). Обрабатывать нажатия на иконку приложения можно в этом же методе, она имеет ID android.R.id.home. Чтобы добавить на ActionBar кнопку «Вверх» («Up Button»), нужно использовать метод ActionBar.setDisplayHomeAsUpEnabled(boolean showHomeAsUp):
Поиск
Иногда нужно сделать поиск, например, как в Google Play. На помощь приходит ActionView. Открываем res/menu/main.xml и удаляем 3 последних элемента — они нам не нужны, а место занимать будут. Вместо них добавляем один новый:
атрибут sabd:actionViewClass=«android.support.v7.widget.SearchView» обозначает, какой View будет использован вместо обычного. Текст collapseActionView в атрибуте sabd:showAsAction говорит о том, что ActionView может быть сворачиваться в кнопку или разворачиваться на всю ширину по нажатию. Чтобы использовать его в Activity, изменим код MainActivity:
Запускаем приложение и видим:
Нажимаем на кнопку поиска:
Кстати, клавиатура появляется автоматически. Выйти из режима поиска можно, нажав на кнопку Вверх в левой части ActionBar или нажав на аппаратную кнопку назад.
В методе onQueryTextChange() мы получаем текст из поля ввода, когда пользователь набирает очередную букву. В методе onQueryTextSubmit(String text) нам даётся текст, который пользователь ищет. У SearchView есть такие полезные методы:
setQuery(CharSequence query, boolean submit) — изменяет текст в поле ввода на тот, который ему передают, опционально делает его конечным (начинает поиск)
getQuery() — возвращает текст, который сейчас есть в поле ввода
setQueryHint(CharSequence hint) — изменяет подсказку на ту, которую ему передают
getQueryHint() — возвращает подсказку
setSuggestionsAdapter(CursorAdapter adapter) — добавляет выпадающий список, как у AutoCompleteTextView
getSuggestionsAdapter() — возвращает адаптер этого списка
setOnCloseListener(SearchView.OnCloseListener listener) — ставит на него обработчик закрытия
setOnSuggestionListener(SearchView.OnSuggestionListener listener) — ставит на него обработчик нажатия на элемент выпадающего списка
Заключение
А ребята из гугла молодцы, не забывают о поддержке старых версий своей ОС. Например, фрагменты, ViewPager и NavigationDrawer с API v4 доступны, Actionbar – с API v7. Хотя мне кажется, что всё это было сделано ради Android 2.3, а более ранние платформы – так, «за компанию».
Буду рад, если эта статья кому-нибудь поможет 🙂
Часть 2 — Навигация с помощью вкладок и выпадающего списка
Часть 3 — Дополнительные функции
Источник