Android меню

Меню вибору опцій (Options Menu)

За меню відповідає клас android.view.Menu. Кожна активність пов'язана з одним об'єктом меню. Саме меню містить пункти меню (клас android.view.MenuItem) і підміню (клас android.view.SubMenu).

Коли меню відкривається вперше, Android викликає метод onCreateOptionsMenu (). передаючи в якості параметра об'єкт Menu. Меню можна створювати у вигляді ресурсів в XML-файлі або використовувати метод add ().

У стандартному проекті при виборі звичайного шаблону вже є заготівля для меню з одного пункту Settings і виклик методу для меню (ви про це вже знаєте).

Створення меню за допомогою ресурсів

Розглянемо роботу з меню через ресурси. Для створення меню використовуються ресурси, які повинні зберігатися в XML-файлі. Сам файл повинен знаходитися в папці res / menu / вашого проекту. Меню складається з наступних елементів:

Визначає меню, яке буде містити пункти меню. елемент повинен бути кореневим елементом в XML-структуру файлу і може містити один або кілька елементів і Створює безпосередньо пункти меню. Даний елемент може мати вкладений елемент для створення підміню При бажанні можете також використовувати невидимий контейнер для елементів . Це дозволяє досягти деяких ефектів

Припустимо, ми вирішили використовувати меню для якої-небудь гри. Створимо новий файл game_menu.xml:

Ми створили меню з двома пунктами. Кожен пункт включає в себе наступні атрибути:

android: id Ідентифікатор пункту меню, за яким програма може розпізнати при виділенні пункту меню користувачем android: title Текст, який буде виводитися в меню

Існують і інші атрибути для елемента item. наприклад android: icon = "@ drawable / home" дозволить також вивести значок для пункту меню, а android: enabled = "false" дозволяє зробити пункт меню недоступним.

Атрибут android: titleCondensed застосовується в тому випадку, якщо звичайний заголовок занадто широкий і не «поміщається» в обраному елементі меню.

Атрибут android: orderInCategory визначає порядок, в якому відображаються елементи меню MenuItems.

При створенні меню ми вказали на строкові ресурси @ string / new_game і @ string / help. Необхідно додати нові рядки в файлі strings.xml:

Тепер потрібно внести зміни в класі активності, в якому буде виводитися меню. Програма повинна конвертувати створений нами ресурс меню в програмний об'єкт. Для цієї мети існує спеціальний метод MenuInflater.inflate (). який викликається в спеціальному методі зворотного виклику onCreateOptionsMenu (). Даний метод і призначений для виведення меню при натисканні кнопки MENU на пристрої:

Після вставки коду середовище розробки попросить імпортувати відсутні простору імен.

Метод onCreateOptionsMenu () метод ініціює перша поява меню на екрані і приймає як параметр об'єкт Menu (для старих пристроїв). Ви можете зберегти посилання на меню і використовувати її в будь-якому місці коду, поки метод onCreateOptionsMenu () знову не буде викликаний. Вам необхідно завжди використовувати реалізацію цього обробника з батьківського класу, тому як вона при необхідності автоматично включає в меню додаткові системні пункти. У нових пристроях метод викликається при створенні активності. Метод повинен повертати значення true. щоб меню було видимим на екрані.

Запустивши програму, натисніть кнопку MENU на емуляторі, щоб побачити створене меню.

Android меню

Метод getMenuInflater () повертає екземпляр класу MenuInflater. який ми використовуємо для читання даних меню з XML.

Як бачите, меню з'являється в нижній частині екрана. Всього можна одночасно вивести на екран шість пунктів меню. Якщо пунктів більше, то буде виведено п'ять пунктів плюс шостий пункт More. який дозволить побачити інші пункти. Давайте перевіримо і додамо нові пункти меню.

Спочатку додамо шість пунктів.

Android меню

Додамо ще один пункт до меню, щоб їх стало сім.

Android меню

Вибір пунктів меню

Ми навчилися створювати меню. Але поки воно марно, так як пункти меню ніяк не реагують на наші натискання. Для обробки натискань пунктів меню служить метод onOptionsItemSelected (). Метод розпізнає пункт, вибраний користувачем, через MenuItem. Ми можемо тепер визначити обраний пункт через виклик getItemId (). який повертає ідентифікатор пункту меню. Далі через оператор switch нам залишається визначити потрібні команди:

Відкрийте програму, викличте меню і виберіть перший або другий пункт меню. У текстовому полі має з'явитися повідомлення.

Android меню

У наведеному прикладі getItemId () запитує ID для обраного пункту меню і починає порівнювати через оператор вибору switch з ідентифікаторами, які ми поставили в XML-ресурсах. При виявленні потрібного ідентифікатора виконується оброблювач для заданого пункту меню. Якщо програма нічого не виявить, то виконується оператор default. який повертає super class.

В Android 3.0 можна додати атрибут android: onClick в ресурсах меню, і вам вже не потрібно використовувати onOptionsItemSelected (). За допомогою android: onClick ви можете вказати потрібний метод при виборі пункту меню.

Програмне створення меню

Розглянемо програмне створення меню для повноти картини. Нам знадобиться визначити кілька констант для пунктів меню:

У методу add () є чотири параметри:

  • ідентифікатор групи - дозволяє пов'язувати пункт меню з групою інших пунктів цього меню
  • ідентифікатор пункту для обробника події вибору пункту меню
  • порядок розташування пункту в меню - дозволяє визначати позицію в меню. За замовчуванням (Menu.NONE або 0) пункти йдуть в тому порядку, як задано в коді
  • заголовок - текст, який виводиться в пункті меню. Можна використовувати строковий ресурс

Метод повертає об'єкт MenuItem. який можна використовувати для установки додаткових властивостей, наприклад, для помістити позначку, гарячу клавішу і т.д.

Якщо ви хочете створити меню зі значками, то скористайтеся методом setIcon ()

Нагадаємо ще раз, що значки можна додати тільки до шести пунктам меню (або до п'яти, якщо пунктів більше шести).

Метод onCreateOptionsMenu викликається системою тільки один раз при створенні меню. Якщо вам потрібно оновити меню під час роботи програми, то використовуйте метод зворотного виклику onPrepareOptionsMenu ().

При виборі пункту меню викликається метод onOptionsItemSelected. який передає об'єкт MenuItem - пункт меню, вибраний користувачем. За допомогою методу getItemId можна отримати ідентифікатор обраного пункту меню. Після ідентифікації пункту меню можна написати код для обробки події вибору меню:

Гарячі клавіші

Також можна задавати гарячі клавіші для швидкого доступу, використовуючи символи клавіатури, за допомогою декількох методів:

  • setAlphabeticShortcut (char) - додає символ
  • setNumericShortcut (int) - додає число
  • setShortcut (char, int) - додає комбінацію символу і числа

Наприклад, якщо задати гарячу клавішу setAlphabeticShortcut ( 'q') ;. то при відкритті меню (або при утриманні клавіші MENU) натискання клавіші Q вибере даний пункт меню. Ця гаряча клавіша (або поєднання клавіш) буде показана як підказка, що відображає нижче імені пункту меню. У нових клавіатурах є окрема клавіша Ctrl. яка працює також, як на звичайних клавіатурах.

Швидкий доступ можна створити і через XML: android: alphabeticShortcut = "c".

Обробляти натискання можна через метод активності onKeyShortcut ():

створення підміню

Підміню можна додати в будь-яке меню, крім іншого підміню. Підміню створюється в методі зворотного виклику onCreateOptionsMenu () за допомогою методу addSubMenu (). який повертає об'єкт SubMenu. В об'єкт SubMenu можна додати додаткові пункти до цього меню, використовуючи метод add (). наприклад:

Тепер при виборі пункту меню з'явиться ще одне вікно з підменю. Спробуйте самі.

Додавання прапорців і перемикачів

В пункти меню можливе додавання прапорців або перемикачів. Щоб додати прапорець або перемикач для окремого елемента меню, необхідно використовувати метод setCheckable ():

Якщо є необхідність додати кілька пунктів меню з прапорцями або перемикачами, то можна об'єднати їх в групи меню, створивши окремий ідентифікатор. Пункт меню додається в групу через метод add (). передавши йому в якості першого параметра ідентифікатор групи меню. Припустимо, ми оголосили ідентифікатори для групи меню Колір і елементів меню для установки кольору:

Тепер для створення групи меню з прапорцями потрібно призначити ідентифікатор групи на кожен пункт меню і викликати метод setGroupCheckable () для всієї групи (І тут не потрібно викликати метод setCheckable () для кожного пункту меню):

У методу setGroupCheckable () три параметра:

  • перший параметр - ідентифікатор групи меню;
  • другий параметр - true, якщо в групі дозволені перемикачі або прапорці;
  • третій параметр - встановлює єдиний (true) або множинний (false) вибір пунктів меню. Цей параметр фактично визначає зовнішній вигляд меню - це буде меню з перемикачами або прапорцями.

Для управління станом прапорців і перемикачів в обробнику події вибору пункту меню потрібно написати наступне:

Запустіть проект, викличте меню і виберіть пункт меню Колір. У вас з'явиться підменю з трьома пунктами (Червоний, Зелений, Синій) у вигляді прапорців. Стан прапорців і перемикачів обробляється в коді програми і зберігається при повторних викликах меню.

Можна відразу призначити намір вибраного пункту меню через метод setIntent (), який спрацює при натисканні цього пункту, якщо ця подія не було перехоплено обработчиками onMenuItemClickListener (устар.) Або onOptionsItemSelected. Спрацювавши, намір передається в метод startActivity.

Програмне відкриття або закриття меню

Якщо вам з якихось причин потрібно програмно відкрити меню (наприклад, в демонстраційних цілях), то використовуйте метод openOptionsMenu ():

Для програмного закриття меню використовуйте метод closeOptionsMenu (). втім у мене повторний виклик методу openOptionsMenu () також закриває меню.

Програмне видалення пункту меню

Припустимо, ми визначили пункт меню в xml-файлі:

Щоб видалити явно зайвий пункт меню з нашої програми про котів, потрібно отримати доступ до пункту меню через метод findItem () і зробити його невидимим. Посилання на об'єкт Menu потрібно передати в метод onCreateOptionsMenu. щоб програма дізналася про зміну складу меню.

Але у даного рішення є недолік, якщо ми повернемо екран, то активність пересоздатся і віддалене меню знову з'явиться. Як же нам позбутися від сраний песика?

Треба запам'ятати стан пункту меню і зберегти його в об'єкті типу Bundle в методі onSaveInstanceState. а в методі onCreate () витягти збережене стан і передати методу onPrepareOptionsMenu. який викликається перед показом меню на екрані:

Визначити наявність кнопки Menu

Розмітка для меню

У сучасних пристроях меню є частиною ActionBar. І ви можете налаштувати розмітку меню через XML.

Припустимо, ви вибрали такий варіант:

В атрибуті showAsAction не використовуйте значення never. інакше розмітку не побачите. Сама розмітка задана через атрибут actionLayout. Код для розмітки:

Меню в фрагментах

Меню може бути не тільки частиною активності, але і частиною фрагмента. Принцип роботи практично не відрізняється. У фрагмента є відповідний метод.

FragmentManager відповідає за виклик onCreateOptionsMenu () при отриманні активністю зворотного виклику onCreateOptionsMenu () від системи. Ви повинні явно повідомити менеджеру FragmentManager. що фрагмент повинен отримати виклик onCreateOptionsMenu (). Для цього викликається метод setHasOptionsMenu ():

Схожі статті