Pull to refresh

ActionBar на Android 2.1+ с помощью SupportLibrary

Reading time 6 min
Views 44K
Здравствуй, Хабрахабр!

Недавно я писал о том, что 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 — Дополнительные функции
Only registered users can participate in poll. Log in, please.
А какие версии Android поддерживаете вы?
1.31% Android 1.5+ 9
1.45% Android 1.6+ 10
11.9% Android 2.1+ 82
20.46% Android 2.2+ 141
32.22% Android 2.3+ 222
1.89% Android 3.0+ 13
0.15% Android 3.1+ 1
0.29% Android 3.2+ 2
18.87% Android 4.0+ 130
2.9% Android 4.1+ 20
2.32% Android 4.2+ 16
6.24% Android 4.3+ 43
689 users voted. 215 users abstained.
Tags:
Hubs:
+13
Comments 16
Comments Comments 16

Articles