Пользователь
0,0
рейтинг
12 августа 2013 в 17:03

Разработка → ActionBar на Android 2.1+ с помощью SupportLibrary tutorial

Здравствуй, Хабрахабр!

Недавно я писал о том, что 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… и ищем нужную нам папку. Путь до неё примерно такой: <ваш SDK>/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)и пишем

<style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light" > . . .


Теперь ActionBar будет виден на любых версиях андроида.

Открываем res/values/strings.xml и добавляем строки:

<string name="action_item_1">Item 1</string>
<string name="action_item_2">Item 2</string>
<string name="action_item_3">Item 3</string>


Открываем res/menus/main.xml и пишем там:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:sabd="http://schemas.android.com/apk/res-auto" >
    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:icon="@android:drawable/ic_menu_add"
        sabd:showAsAction="always" />
    <item
        android:id="@+id/action_item_1"
        android:title="@string/action_item_1"
        android:icon="@android:drawable/ic_menu_delete"
        sabd:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_item_2"
        android:title="@string/action_item_2"
        android:icon="@android:drawable/ic_menu_add"
        sabd:showAsAction="ifRoom|withText" />
    <item
        android:id="@+id/action_item_3"
        android:title="@string/action_item_3"
        android:icon="@android:drawable/ic_menu_add"
        sabd:showAsAction="never" />
</menu> 


Обратите внимание на атрибуты 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), в котором мы и создаём меню:

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;

public class MainActivity extends ActionBarActivity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Log.d("MENU", "Cliced MenuItem is " + item.getTitle());
		return super.onOptionsItemSelected(item);
	}
}


Запускаем приложение и видим наш ActionBar:



Item 2 не отобразился, так как для него не хватило места. Item 3 ни при каких условиях не будет виден, потому что мы выставили атрибут sabd:showAsAction=«never». Добраться до них можно с помощью кнопки «Меню» на устройстве.
Обрабатывать нажатия на элементы меню можно там же, где и раньше — в методе onOptionsItemSelected(MenuItem item). Обрабатывать нажатия на иконку приложения можно в этом же методе, она имеет ID android.R.id.home. Чтобы добавить на ActionBar кнопку «Вверх» («Up Button»), нужно использовать метод ActionBar.setDisplayHomeAsUpEnabled(boolean showHomeAsUp):

image

Поиск


Иногда нужно сделать поиск, например, как в Google Play. На помощь приходит ActionView. Открываем res/menu/main.xml и удаляем 3 последних элемента — они нам не нужны, а место занимать будут. Вместо них добавляем один новый:

<item android:id="@+id/action_search"
    	android:title="@string/action_search"
        android:icon="@android:drawable/ic_menu_search"
        sabd:showAsAction="always|collapseActionView"
        sabd:actionViewClass="android.support.v7.widget.SearchView" />


атрибут sabd:actionViewClass=«android.support.v7.widget.SearchView» обозначает, какой View будет использован вместо обычного. Текст collapseActionView в атрибуте sabd:showAsAction говорит о том, что ActionView может быть сворачиваться в кнопку или разворачиваться на всю ширину по нажатию. Чтобы использовать его в Activity, изменим код MainActivity:

import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity implements OnQueryTextListener {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		
		MenuItem searchItem = menu.findItem(R.id.action_search);
	    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
	    searchView.setQueryHint("Поиск");
	    searchView.setOnQueryTextListener(this);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Log.d("MENU", "Cliced MenuItem is " + item.getTitle());
		return super.onOptionsItemSelected(item);
	}

	public boolean onQueryTextChange(String text_new) {
		Log.d("QUERY", "New text is " + text_new);
		return true;
	}

	public boolean onQueryTextSubmit(String text) {
		Log.d("QUERY", "Search text is " + text);
		return true;
	}
}


Запускаем приложение и видим:

image

Нажимаем на кнопку поиска:



Кстати, клавиатура появляется автоматически. Выйти из режима поиска можно, нажав на кнопку Вверх в левой части 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 — Дополнительные функции
А какие версии Android поддерживаете вы?

Проголосовало 683 человека. Воздержалось 211 человек.

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

@ED98
карма
5,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (16)

  • 0
    Очень интересные результаты голосования сейчас:
    Скриншот
    image
    • 0
      баг хабра)
      попробуй обновить страницу — у меня всё стало на свои места
  • 0
    Если пункты меню собраны в один пункт, то по «железной» кнопке «меню» на Android 2.x попап меню появляется сверху или снизу?
    • 0
      внизу, только оно имеет вот такой вид:

      image
      • 0
        Это у вас четвертый андроид, а djvu спрашивает про 2.x
        • 0
          скрин эмулятора 2.2:

          image
  • +2
    Получается, ActionBarSherlock больше не нужен?

    Кстати, раз зашла речь о support library, поставьте звездочку, кому не трудно, чтобы запилили и PreferenceFragment.
    • +2
      да, но это только в новых проектах, я бы не стал переводить старый с ABS на SupportLib
      • +1
        после добавления ActionBarSherlock приложение хорошо добавляет в весе конечного apk. А как с этим у SupportLib?
        • 0
          добавляет примерно 500-600кб
        • 0
          Даже если добавит оно максимум 1МБ, то ничего страшного не случится. К тому же, до SupportLib, было два варианта, либо использовать ABS, либо писать самому, второй вариант думаю добавил бы побольше.

          Да и сейчас уже не то время, когда память килобайтами считается :)
          • 0
            С тем, что самописный вариант добавит больше не соглашусь.
            Еще давно, когда ABS не был так на слуху, а у меня был LG GT540 с очень ограниченной памятью под приложения и я дрожал за каждый КБ, мною был написан простенький ActionBar, который выглядел как оригинал с 4.0, но весил совсем немного, так как был написан специально под конкретное приложение и не включал ненужных ему навесов.
            • 0
              Да, я согласен с Вами, когда пишешь только полоску c home button, тогда да, это выйдем меньше, просто я имел ввиду полное повторение функционала или хотя бы приближенное.
    • +1
      Еще когда на IO показывали, говорили «если юзаете ABS в проекте — продолжайте юзать».
    • 0
      С ним вряд ли получится, даже сами гугловцы объясняли, что и PreferenceActivity, и PreferenceFragment зависят от закрытых API PreferenceManager (вот там внутри как раз подгрузка структуры настроек из xml-файла и прочая вкуснота). Поэтому простой либой невозможно будет добиться такого результата. Разве что в Google Play Services впихнут что-нибудь.
  • 0
    Спасибо за статью

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