воскресенье, 4 сентября 2011 г.

Меню (Часть 1)

Меню являются важной частью многих android приложений. Оно предоставляет пользователю привычный и удобный способ для выполнения каких-то действий.

Есть три типа меню:
  • Меню параметров (Options Menu) - Это меню, которое появляется, когда пользователь нажимает кнопку Menu на устройстве.
  • Контекстное меню (Context Menu) - появляется при длительном нажатии на экран.
  • Подменю (Submenu) - Дополнительное меню, для одного из пунктов основного меню
SDK Android предлагает удобные инструменты для создания меню.

Пост оказался очень длинным, поэтому разбит на две части.

Основной класс отвечающий за меню android.view.Menu. Для элементов меню используется класс android.view.MenuItem, а для подменю класс android.view.Submenu.
Любая деятельность (Activity) связана с объектом класса Menu. Android создает для каждой деятельности отдельное меню и передает его методу bool onCreateOptionsMenu (Menu menu). Данный метод позволяет заполнить созданное меню нужными элементами. Метод возвращает true, чтобы меню было видимым и false — невидимым.

Добавить элемент в меню можно с помощью метода add класса Menu:
  1. MenuItem add (int groupId, int itemId, int order, charSequence Title)  
где groupId — id группы. Элементы меню можно объединять в группы, присваивая каждой из них групповой ID. В классе Menu есть несколько методов для управления группами элементов.
itemId — id конкретного элемента меню
order — порядок сортировки
Title — заголовок элемента меню

Создание меню
Создадим простое приложение, в котором постараемся рассмотреть основные принципы работы с меню. Создаем новый проект (у меня это JustMenu) и добавляем метод onCreateOptionsMenu
  1. public class JustMenu extends Activity {  
  2.       
  3.     Menu myMenu;  
  4.     boolean isGroupVisible = true;  
  5.     boolean isGroupEnabled = true;  
  6.     boolean isGroupCheckable = false;  
  7.     boolean isGroupExists = true;  
  8.       
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.main);  
  13.     }  
  14.       
  15.     @Override  
  16.     public boolean onCreateOptionsMenu(Menu menu) {  
  17.           
  18.         myMenu = menu;  
  19.   
  20.         menu.add (Menu.FIRST, 11"SubMenu");  
  21.         menu.add (Menu.FIRST, 22"Disable Items");  
  22.         menu.add (Menu.FIRST, 33"Hide Items");  
  23.         menu.add (Menu.FIRST, 44"Set Checkable Items");  
  24.         menu.add (Menu.FIRST, 55"Remove Items");  
  25.           
  26.         menu.add (Menu.CATEGORY_SECONDARY, 66"Item 1");  
  27.         menu.add (Menu.CATEGORY_SECONDARY, 77"Item 2");  
  28.         menu.add (Menu.CATEGORY_SECONDARY, 88"Item 3");  
  29.     return true;  
  30.     }  
  31. }  

Menu.FIRST и Menu.CATEGORY_SECONDARY - две константы в классе Menu, которые можно использовать как ID групп. О других константах можно почитать тут.

Мы добавили в класс переменную myMenu и инициализировали ее в методе onCreateOptionsMenu, для того чтобы можно было обращаться к меню из других мест программы, и четыре булевых переменных (их смысл будет понятен ниже). В группе Menu.FIRST находится пять элементов, а в группе Menu.CATEGORY_SECONDARY - три. Причем id элементов и порядок сортировки от группы не зависит.

Запускаем:


Мы видим 5 добавленных элементов и элемент «More» который мы не добавляли, он появляется автоматически, когда количество элементов меню больше шести. Остальные элементы (в нашем случае это все элементы группы Menu.CATEGORY_SECONDARY) появляются по нажатию на этот пункт (такие элементы называются расширенным меню)



Выбор пункта меню
При нажатии на любой другой элемент, меню просто закрывается. Для выполнения каких-то действий при выборе пункта меню можно использовать метод onOptionsItemSelected (MenuItem item), которому передается ссылка на выбранный пункт меню.
  1. @Override  
  2. public boolean onOptionsItemSelected (MenuItem item) {  
  3.           
  4.     if (item.getItemId() == 1) {   
  5.         // Элемент «SubMenu», пока ничего не выполняем,   
  6.         // так как на этом элементе позже будет создано подменю  
  7.     }  
  8.           
  9.     if (item.getItemId() == 2) {   
  10.         // меняем значение на противоположенное  
  11.         isGroupEnabled = !isGroupEnabled;  
  12.         // Активируем или отключаем элементы меню в группе Menu.CATEGORY_SECONDARY  
  13.         myMenu.setGroupEnabled(Menu.CATEGORY_SECONDARY, isGroupEnabled);  
  14.         // Меняем заголовок тнажатого элемента меню  
  15.         item.setTitle (isGroupEnabled ? "Disable Items" : "Enable Items");  
  16.     }  
  17.       
  18.     else if (item.getItemId() == 3) {   
  19.         isGroupVisible = !isGroupVisible;  
  20.         // Показываем или скрываем элементы меню в группе  
  21.         myMenu.setGroupVisible(Menu.CATEGORY_SECONDARY, isGroupVisible);  
  22.         item.setTitle (isGroupVisible ? "Hide Items" : "Show Items");  
  23.     }  
  24.           
  25.     else if (item.getItemId() == 4) {  
  26.         isGroupCheckable = !isGroupCheckable;  
  27.         // Отображаем или скрываем галочку радос с элементами меню  
  28.         myMenu.setGroupCheckable(Menu.CATEGORY_SECONDARY, isGroupCheckable, false);  
  29.         item.setTitle (isGroupCheckable ? "Unset Checkable Items" : "Set Checkable Items");  
  30.     }  
  31.       
  32.     else if (item.getItemId() == 5) {  
  33.         isGroupExists = !isGroupExists;  
  34.         if (!isGroupExists)  
  35.             // удаляем все элементы меню из группы  
  36.             myMenu.removeGroup(Menu.CATEGORY_SECONDARY);  
  37.         else {  
  38.            // Добавляем элементы меню в группу  
  39.             myMenu.add (Menu.CATEGORY_SECONDARY, 66"Item 1");  
  40.             myMenu.add (Menu.CATEGORY_SECONDARY, 77"Item 2");  
  41.             myMenu.add (Menu.CATEGORY_SECONDARY, 88"Item 3");  
  42.           
  43.            // Восстанавливаем значения Enable (доступность), Visible (видимость) и Checkable (отображение галочек)  
  44.             myMenu.setGroupEnabled(Menu.CATEGORY_SECONDARY, isGroupEnabled);  
  45.             myMenu.setGroupVisible(Menu.CATEGORY_SECONDARY, isGroupVisible);  
  46.             myMenu.setGroupCheckable(Menu.CATEGORY_SECONDARY, isGroupCheckable, false);  
  47.         }  
  48.         item.setTitle (isGroupExists ? "Remove Items" : "Create Items");  
  49.     }  
  50.           
  51.     else if (item.getItemId() == 7 || item.getItemId() == 8 || item.getItemId() == 9) {  
  52.         if (item.isCheckable())  
  53.             item.setChecked(!item.isChecked());  
  54.     }  
  55.     return true;  
  56. }  


В метод boolean onOptionsItemSelected (MenuItem item) передается выбранный элемент меню — item.
Метод item.getItemId() - Возвращает id элемента, в зависимости от него мы выполняем соответствующие действия.

Методы для работой с группами элементов меню:
void setGroupEnabled (int group, boolean enabled) — Устанавливает доступность элементов группы, где group — id группы, enabled — true(доступны) или false (не доступны)

void setGroupVisible (int group, boolean visible) — Устанавливает видимость элементов

void setGroupCheckable (int group, boolean checkable, boolean exclusive) — Отображение галочек рядом с элементами, где exclusive — исключающая отметка, при exclusive = true, можно выбрать только один из элементов группы

void removeGroup (int groupId) — удаление группы элементов


Подменю
Теперь сделаем подменю у первого элемента нашего меню (с названием Submenu). Для того чтобы добавить подменю используется метод SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) класса Menu. Этот метод очень похож на метод add. Метод возвращает объект класса SubMenu, который является производным от Menu, поэтому ему можно добавить элементы по тому же принципу, что и к обычному Menu (с помощью метода add). Добавить подменю к подменю не получиться (компилятор не выдаст ошибки, но во время выполнения программа выдаст исключение).

В методе onCreateOptionsMenu заменим строчку
  1. // menu.add (Menu.FIRST, 1, 1, "SubMenu");  
  2.    
  3. SubMenu sm = menu.addSubMenu (Menu.FIRST, 11"SubMenu");  
  4. sm.add(Menu.FIRST, 100100"SubMenu 1");  
  5. sm.add(Menu.FIRST, 101101"SubMenu 2");  
  6. sm.add(Menu.FIRST, 102102"SubMenu 3");  


Теперь при нажатии на элемент SubMenu откроется новое меню.


Обработка нажатия на элементы подменю, происходит также в методе onOptionsItemSelected.

Во второй части рассмотрим меню с иконками, контекстное меню, а также создание меню в xml. Там же можно скачать исходники.
Меню (Часть 2)

Комментариев нет:

Отправить комментарий