Содержание
Предоставить пользователю меню опций (вызывается по нажатию кнопки «Menu» девайса) и контекстного меню — это хороший путь улучшить юзабилити, за которое вам скажут спасибо. В статье мы рассмотрим создание ContextMenu, OptionsMenu, CheckableMenu …
Постановка задачи
Создадим две активности, одна из них будет содержать следующую функциональность:
- Меню опций, активируемое нажатием соответствующей кнопки на девайсе (в случае планшета это будет виртуальная кнопка)
- Меню должно включать в себя: кнопку перехода на вторую активность, группу из 2 кнопок, кнопку, меняющую видимость группы кнопок, подменю.
И для второй активности:
- Контекстное меню, активируемое длинным нажатием на экран
- Контекстное меню содержит CheckableGroup
Шаг 1: описание меню в xml-файлах
Для описания меню (как контекстного, так и меню опций) создадим папку res/menu и два файла в ней: options.xml и context.xml . Они будут содержать описание вида нашего меню, приведу код:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Простые пункты меню -->
<item
android:id="@+id/option_button_next"
android:icon="@android:drawable/ic_media_next"
android:title="Сменить активнось"/>
<item
android:id="@+id/option_button_show_group"
android:icon="@android:drawable/ic_input_delete"
android:title="Показать группу 1"/>
<!-- Описание пункта с подменю -->
<item
android:id="@+id/options_submenu"
android:icon="@android:drawable/ic_menu_more"
android:title="Подменю">
<!-- Описание самого подменю -->
<menu>
<item
android:id="@+id/submenu_button_say"
android:title="Сказать привет"/>
<item
android:id="@+id/submenu_button_cancel"
android:title="Отмена"/>
</menu>
</item>
<!-- Объединение элементов в группы -->
<group
android:id="@+id/group_1"
android:visible="false">
<item
android:id="@+id/group_button_1"
android:icon="@android:drawable/ic_menu_camera"
android:title="Кнопка 1 группы"/>
<item
android:id="@+id/group_button_2"
android:icon="@android:drawable/ic_menu_compass"
android:title="Кнопка 2 группы"/>
</group>
</menu>
Описание контекстного меню будет иметь вид:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:checkableBehavior="single">
<item
android:id="@+id/button_red"
android:title="Red"/>
<item
android:id="@+id/button_green"
android:title="Green"/>
<item
android:id="@+id/button_blue"
android:title="Blue"/>
</group>
</menu>
Как вы думаю заметили, содержание отличается не сильно. Давайте пройдемся по его элементам:
- Элемент представляет собой пункт меню, его атрибуты понятны, отмечу лишь что ресурсы вида @android:drawable/ic_menu_ это системные ресурсы для представления картинок пунктов меню, используйте их, если ваше приложение не требует изощренного дизайна.
- Конструкция вида:
<item>
<menu>
....
</menu>
</item>служит для представления подменю. Вложенность может быть только в один уровень. Чаще всего этого достаточно.
- Элемент позволяет объединять пункты в группы, это может быть необходимо для создания RadioButton, как во втором файле, либо для управления группой как одним элементом с помощью методов setGroupVisible(), setGroupEnabled() и setGroupCheckable() .
Замечу, что в описание разметки для контекстного меню атрибут icon не указывался, так как отображаться он не будет. Хотя его указание не помещает работе программы.
Шаг 2: java-описание логики работы меню
Дело это не сложное, нужно лишь перегрузить пару методов и уметь пользоваться switch-case:
package by.idev.android.menutrial.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import by.idev.android.menutrial.R;
public class IdevMenuTrialActivity extends Activity {
Menu menu;
boolean isGroupVisible = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
// Метод вызывается при нажатии на кнопку Menu девайса
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options, menu);
this.menu = menu;
return super.onCreateOptionsMenu(menu);
}
@Override
// Обработка нажатия на пункт меню
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.option_button_next: {
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
return true;
}
case R.id.option_button_show_group: {
isGroupVisible = !isGroupVisible;
String itemTittle = isGroupVisible ? "Спрятать группу 1"
: "Показать группу 1";
item.setTitle(itemTittle);
// Пример обработки группы
menu.setGroupVisible(R.id.group_1, isGroupVisible);
return true;
}
case R.id.group_button_1:
case R.id.group_button_2: {
String message = "Была нажата кнопка "+item.getTitle();
Toast.makeText(this, message, Toast.LENGTH_SHORT)
.show();
return true;
}
case R.id.submenu_button_say: {
Toast.makeText(this, "Не дави на меня", Toast.LENGTH_LONG).show();
return true;
}
case R.id.submenu_button_cancel:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
В этом коде мы описали логику работы активности по работе с меню опций, основные действия тут таковы:
- Перегрузить метод onCreateOptionsMenu(), он вызывается всякий раз при появлении меню на экране. В нем мы должны «надуть» меню в соответствии с его разметкой при помощи MenuInflator.
- Перегрузить метод onOptionsItemselected(), который инкапсулирует логику по определению того, какой пункт меню был выбран и что по этому поводу нужно сделать.
Теперь внимательно посмотрите на описание активности с контекстным меню:
package by.idev.android.menutrial.activities;
import by.idev.android.menutrial.R;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
public class NextActivity extends Activity {
LinearLayout layout;
int currentItemIndex = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.next);
/*Чтобы элемент интерфейса имел
* контекстное меню, его нужно
* зарегистрировать*/
layout = (LinearLayout) findViewById(R.id.next_layout);
registerForContextMenu(layout);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Set background to:");
//Если вы хотите сделать несколько
// контекстных меню для разные элементов
// интерфейса, то отличать их можно по id
switch (v.getId()) {
case R.id.next_layout:
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.context, menu);
}
menu.getItem(currentItemIndex).setChecked(true);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
item.setChecked(true);
switch (item.getItemId()) {
case R.id.button_red: {
currentItemIndex = 0;
layout.setBackgroundColor(Color.RED);
return true;
}
case R.id.button_green: {
currentItemIndex = 1;
layout.setBackgroundColor(Color.GREEN);
return true;
}
case R.id.button_blue: {
currentItemIndex = 2;
layout.setBackgroundColor(Color.BLUE);
return true;
}
default:
return super.onContextItemSelected(item);
}
}
}
Тут как мы и ожидали все очень похоже, изменились только названия методов и появилась привязка (регистрация) контекстного меню к виджету. Основные действия такие:
- При создании активности применить метод registerForContextMenu() к виджетам которым вы хотите добавить контекстное меню.
- Перегрузить метод onCreateContextMenu(), аналогичный методу описанному выше. Но как видим, параметров здесь больше, один из них — это виджет на который мы давили пальцами чтобы вызвать меню, второй — информация об этом виджете, например это может быть позиция элемента в списке.
- Перегрузить метод onContextItemSelected(), который в точности повторяет соответствующий метод для меню опций.
Вот и все простые сложности!
Исходники можно скачать тут
Happy Coding!
Последни статьи
-
Mobile Developer & Business Day в Минске: для разработчиков и заказчиков мобильных приложений
-
#Droidcon Stockholm 2014 или какими я хочу видеть Android-конференции [дополняется]
-
[Swift] Урок 2 — Делаем простой конвертер для iOS
-
Опубликована программа MobileOptimized 2014: лидеры мнений мобильной разработки со всего мира соберутся в Минске!
-
[Swift] Урок 1 — Пишем программу «Hello, World» на Swift языке под iOS
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: