Панель действий является важным элементом дизайна, обычно в верхней части каждого экрана приложения, который обеспечивает согласованный знакомый вид между приложениями Android. Он используется для обеспечения лучшего взаимодействия с пользователем и поддержки, поддерживая простую навигацию по вкладкам и раскрывающимся спискам Он также предоставляет пространство для идентификации приложения или действия, что позволяет пользователю узнать свое местоположение в приложении и обеспечивает легкий доступ к действиям, которые можно выполнить.
Панель действий была введена в Android 3.0, хотя поддержка более старых версий может быть достигнута с помощью библиотеки поддержки Android . Перед выпуском меню параметров обычно использовалось для предоставления действий и функций, которые теперь отображаются на панели действий. Панель действий по умолчанию включена во все действия для приложений с minSdkVersion
В этом руководстве рассматривается настройка панели действий и рассматриваются различные конфигурации, которые она предлагает.
Настройка панели действий
Для начала мы собираемся создать новый проект. Мы не будем использовать библиотеку поддержки Android, поэтому убедитесь, что вы выбрали минимальную версию SDK 11 или выше. Когда вы запустите свой проект, панель действий будет включена в верхней части экрана вашего приложения. Он включен во все действия, которые используют или наследуют от темы Theme.Holo, которая используется по умолчанию, если для minSdkVersion
Типичная панель действий показана на следующем рисунке.
Панель действий состоит из:
- Значок приложения — используется для обозначения вашего приложения логотипом или значком.
- Управление представлением — это также может быть использовано для определения приложения или конкретной активности пользователя по заголовку. Если ваше приложение имеет разные представления, его также можно использовать для их отображения и обеспечения легкого переключения между представлениями.
- Кнопки действий — они используются для отображения наиболее важных и / или часто используемых действий. Если недостаточно места для отображения всех кнопок действий, те, которые не помещаются, автоматически перемещаются в переполнение действий.
- Переполнение действия — это используется для менее используемых действий.
Добавление действий на панель действий
Чтобы добавить действия на панель действий, создайте файл XML в каталоге res/menu
Можно определить действия в коде Java, но вы будете писать меньше кода, если будете использовать XML. Содержимое res/menu/main_activity_bar.xml
В этом примере мы используем пакет значков панели действий для значков действий. Загрузите его и скопируйте необходимые значки в каталог res/drawable-xxxx
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_record"
android:icon="@drawable/ic_action_video"
android:title="@string/action_record"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_save"
android:icon="@drawable/ic_action_save"
android:title="@string/action_save"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_label"
android:icon="@drawable/ic_action_new_label"
android:title="@string/action_label"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_play"
android:icon="@drawable/ic_action_play"
android:title="@string/action_play"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:showAsAction="never" />
</menu>
Затем добавьте строковые литералы в res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ActionBar</string>
<string name="action_settings">Settings</string>
<string name="action_search">Search</string>
<string name="action_record">Record Video</string>
<string name="action_save">Save</string>
<string name="action_label">Add Label</string>
<string name="action_play">Play Video</string>
<string name="hello_world">Hello world!</string>
</resources>
Атрибут icon
title
Чтобы отобразить title
withText
showAsAction
Например, вы можете использовать android:showAsAction="ifRoom|withText"
Чтобы действие всегда отображалось, используйте always
showAsAction
Тем не менее, это не рекомендуется, так как это может вызвать нежелательные эффекты макета на небольших экранах. Если необходимо, ограничьте его одним или двумя пунктами.
Вы всегда должны определять атрибут title
- Заголовок будет использоваться в переполнении, если на панели действий недостаточно места для элемента действия.
- Для пользователя может быть неочевидным, что делает элемент действия только из-за его значка, поэтому предоставление заголовка позволяет ему долго нажимать на него, чтобы открыть подсказку, отображающую заголовок.
- Заголовок обеспечивает доступ для пользователей с нарушениями зрения, так как программа чтения с экрана может прочитать заголовок пункта меню.
Далее нам нужно реализовать метод обратного вызова onCreateOptionsMenu()
Это раздувает ресурс меню в заданный объект Menu
Код для этой функции показан ниже.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_bar, menu);
return super.onCreateOptionsMenu(menu);
}
Запустите проект, и вы увидите нечто похожее на следующий рисунок. Некоторые кнопки действий отображаются на панели действий, а остальные можно увидеть в расширенном переполнении действий. При переходе в горизонтальный режим панель действий автоматически адаптируется к новой ширине и отображает больше действий в соответствии с рекомендациями, приведенными в файле XML.
Разделение панели действий
Поскольку элементы действий совместно используют область действия со значком и заголовком приложения, вы можете разделить панель действий так, чтобы элементы действия отображались в нижней части экрана. Это даст им больше места, и, таким образом, больше элементов будет видно пользователю. Если места достаточно, например, на больших экранах или в альбомном режиме, панель действий не будет разделена.
Чтобы разделить панель действий, добавьте android:uiOptions="splitActionBarWhenNarrow"
Это поддерживает только API уровня 14 и выше. Чтобы добавить поддержку более низких уровней, используйте следующий элемент meta-data
<activity
android:name="com.example.actionbar.MainActivity"
android:label="@string/app_name"
android:uiOptions="splitActionBarWhenNarrow" >
<meta-data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Скрытие панели действий
Возможно, вы не захотите, чтобы панель действий всегда была видна пользователю. Типичным примером этого является приложение Галерея, которое скрывает панель действий, когда пользователь смотрит на изображение, и показывает панель действий, когда они касаются изображения. Чтобы переключать видимость панели действий на ощупь, добавьте следующее в свой файл активности.
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
toggleActionBar();
}
return true;
}
private void toggleActionBar() {
ActionBar actionBar = getActionBar();
if(actionBar != null) {
if(actionBar.isShowing()) {
actionBar.hide();
}
else {
actionBar.show();
}
}
}
При запуске приложения вы сможете показать / скрыть панель действий, нажав на экран. Вы заметите, что содержимое на экране меняет положение с каждым показом / скрытием. Это связано с тем, что когда вы скрываете / отображаете панель действий, активность изменяется, влияя на размер и позицию контента. Чтобы предотвратить это, вы должны вместо этого наложить панель действий, как описано далее.
Наложение панели действий
Наложение панели действий обеспечивает лучший способ скрытия / показа, поскольку активность не изменяется при каждом скрытии / показе, что позволяет вашему контенту оставаться на месте. Вы можете включить наложение, установив для android:windowActionBarOverlay
true
Вы должны использовать тему Theme.Holo (или один из ее потомков). Если ваш minSdkVersion
В res/values/styles.xml
<resources>
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowActionBarOverlay">true</item>
</style>
</resources>
Запустите приложение и обратите внимание, что содержимое на экране не меняет своего положения, когда панель действий скрыта и открыта.
Добавление навигации вверх
Все экраны в вашем приложении, которые не являются основным входом в ваше приложение («домашний» экран), должны предлагать пользователю способ перехода к логическому родительскому экрану в иерархии приложения, нажав кнопку «Вверх» на панели действий. Начиная с уровня API 14, вы можете объявить логического родителя каждого действия, указав атрибут android:parentActivityName
Для поддержки более низких версий activity
android.support.PARENT_ACTIVITY
android:parentActivityName
Мы добавим еще одно действие, чтобы продемонстрировать это. Добавьте другой файл активности с именем SecondActivity
Мы вызываем setDisplayHomeAsUpEnabled()
Это добавит левую каретку рядом со значком приложения. Когда она нажата, действие получает вызов onOptionsItemSelected()
package com.example.actionbar;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.second_activity_bar, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
В res/layout/second_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world_again" />
</RelativeLayout>
Затем добавьте следующие строки в res/values.strings.xml
<string name="hello_world_again">Hello world, again!</string>
<string name="second">Go To Second Activity</string>
<string name="second_activity_title">Second Activity</string>
Затем создайте файл ресурсов для панели действий второго действия. Назовите этот файл res/menu/second_activity_bar.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
Затем добавьте действие в файл манифеста:
<application>
...
<activity
android:name="com.example.actionbar.SecondActivity"
android:label="@string/second_activity_title"
android:parentActivityName="com.example.actionbar.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.actionbar.MainActivity" />
</activity>
...
</application>
Затем добавьте кнопку в основное действие в res/layout/activity_main.xml
<Button
android:id="@+id/second"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/TextView1"
android:layout_centerVertical="true"
android:onClick="openSecondActivity"
android:text="@string/second" />
Также добавьте обработчик onClick
MainActivity.java
Эта функция, показанная ниже, запускает второе действие при нажатии кнопки.
public void openSecondActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
Запустите приложение. На первом экране будет кнопка, которая при нажатии откроет второй экран с панелью действий, показанной ниже. Обратите внимание на каретку, которая перемещается к родительской активности при нажатии.
Интерактивность Action Bar
Пока что мы создали элементы действий, которые ничего не делают при нажатии. Далее мы увидим, как добавить интерактивность на панель действий.
Обработка щелчков на элементах действий
При нажатии действия вызывается метод действия onOptionsItemSelected()
Действие можно определить, вызвав getItemId()
Добавьте метод onOptionsItemSelected()
MainActivity.java
Здесь мы показываем другое сообщение, когда на каждое действие нажимают.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
// Code you want run when activity is clicked
Toast.makeText(this, "Search clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_record:
Toast.makeText(this, "Record clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_save:
Toast.makeText(this, "Save clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_label:
Toast.makeText(this, "Label clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_play:
Toast.makeText(this, "Play clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Виды действий
Представления действий — это интерактивные виджеты, которые отображаются на панели действий вместо кнопок действий. Они позволяют размещать случайно используемые элементы пользовательского интерфейса на панели действий, что позволяет избежать ненужного использования места на экране и переключения действий для их использования.
Чтобы объявить представление действия, используйте actionLayout
actionViewClass
В качестве быстрого примера, чтобы добавить виджет SearchView
res/menu/main_activity_bar.xml
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
При запуске приложения появится окно редактирования текста при нажатии на действие поиска.
Мы добавим наш собственный вид на панель действий. Создайте файл макета с именем res/layout/my_action.xml
Это будет ресурс макета пользовательского представления.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/myActionTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Type here:"
android:gravity="right" />
<EditText
android:id="@+id/myActionEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left" />
</LinearLayout>
Затем добавьте элемент действия в файл res/menu/main_activity_bar.xml
<item android:id="@+id/my_action"
android:icon="@drawable/ic_action_edit"
android:title="My Action"
android:showAsAction="ifRoom|collapseActionView"
android:actionLayout="@layout/my_action" />
Это будет использовать макет, который мы добавили выше. collapseActionView
Нажатие на каретку вверх выходит из вида действия.
Затем обновил основной файл активности MainActivity.java
Обратите внимание на комментарии по всему коду.
package com.example.actionbar;
import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.MenuItemCompat.OnActionExpandListener;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements TextView.OnEditorActionListener {
private MenuItem myActionMenuItem;
private EditText myActionEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_bar, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the edit text view that is part of the action view
if(actionView != null) {
myActionEditText = (EditText) actionView.findViewById(R.id.myActionEditText);
if(myActionEditText != null) {
// We set a listener that will be called when the return/enter key is pressed
myActionEditText.setOnEditorActionListener(this);
}
}
// For support of API level 14 and below, we use MenuItemCompat
MenuItemCompat.setOnActionExpandListener(myActionMenuItem, new OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
if(myActionEditText != null) {
myActionEditText.setText("");
}
return true; // Return true to expand action view
}
});
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
toggleActionBar();
}
return true;
}
private void toggleActionBar() {
ActionBar actionBar = getActionBar();
if(actionBar != null) {
if(actionBar.isShowing()) {
actionBar.hide();
}
else {
actionBar.show();
}
}
}
public void openSecondActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
// Code you want run when activity is clicked
Toast.makeText(this, "Search clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_record:
Toast.makeText(this, "Record clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_save:
Toast.makeText(this, "Save clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_label:
Toast.makeText(this, "Label clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_play:
Toast.makeText(this, "Play clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(keyEvent != null) {
// When the return key is pressed, we get the text the user entered, display it and collapse the view
if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
CharSequence textInput = textView.getText();
// Do something useful with the text
Toast.makeText(this, textInput, Toast.LENGTH_SHORT).show();
MenuItemCompat.collapseActionView(myActionMenuItem);
}
}
return false;
}
}
В этом коде мы получаем представление редактирования текста в макете представления действия myActionEditText
Мы хотим, чтобы операция выполнялась, когда пользователь вводит какой-то текст и нажимает клавишу возврата. По умолчанию, когда пользователь нажимает Return, курсор переходит на новую строку. Вместо этого мы хотим свернуть вид действия и получить ввод пользователя. Это делается методом onEditorAction
Если это Enter, ввод текста захватывается и отображается. Затем вид действия свернут.
Мы устанавливаем слушателя в представлении действия с помощью MenuItemCompat.setOnActionExpandListener
MenuItemCompat
По умолчанию, когда пользователь вводит текст и покидает вид действия, при его повторном расширении предыдущий текст все еще виден. Мы используем onMenuItemActionExpand()
Вывод
Панель действий является важным элементом дизайна, и ее можно использовать для значительного улучшения пользовательского интерфейса приложения. Мы рассмотрели некоторые конфигурации, которые вы можете использовать на панели действий для пользовательского интерфейса вашего приложения, но есть и другие. Для получения дополнительной информации ознакомьтесь с документацией . Вы можете увидеть код, используемый в этой статье на GitHub.