Создание меню. Инженерное меню на Андроид – разбираемся в деталях Выводим скорость интернет-соединения

Когда то давно, лет 5 назад стремительно набирали популярность аппараты с операционной системой Android. Хорошее было время, мир выходил из кризиса, впереди было много интересного и на каждом аппарате была кнопка Меню.
Спустя 2 года парни из Android сообщили о том, что кнопка "меню" на корпусе аппарата теперь уже не модно и можно без неё. С тех пор каждый из нас (Гильдии разработчиков) знает, как вызвать меню на подавляющем большинстве андроид девайсов.
Кому то это покажется страшным баяном, пусть так, но на прошлой неделе мы потратили 2 часа своей жизни на то, чтобы это объяснить пользователю. Мириться с этим было нельзя, поэтому ниже привожу описание того, как вызвать функцию меню на андроид аппаратах.
Вот так выглядят механические кнопки меню на большинстве распространённых устройств:

Причём в большинстве случаев для вызова функции меню достаточно одного короткого касания. Однако, часто вызов меню может быть добавлен к кнопке выбора запущенных приложений. Выглядит она так:


В этом случае меню откроется только при долгом нажатии (так называемый лонг-клик)! То есть не просто ткнули пальцем, а ткнули и подержали . Многие говорят после этого Вау!

Владельцам планшетов советую обратить внимание на рабочую область экрана, именно там чаще всего находятся кнопки, в том числе и Меню.


Причём не всегда максимально справа, но выглядит эта кнопка именно так.
На свежих версиях Android OS кнопка меню выглядит так.

Android в своем стандартном виде выглядит бедно. Да, все необходимые функции вроде бы есть, а включить показ процентов батареи до сих пор нельзя. Есть красивая анимация загрузки, но толку от нее - ноль. Поддержки тем как не было, так и нет. И что теперь - ставить очередной кастом, завтрашняя ночная сборка которого обязательно заглючит? Нет, мы все сделаем, имея только root. Читайте дальше и узнаете как изменить интерфейс Android.

ПОДГОТОВИТЕЛЬНЫЕ ШАГИ

Для выполнения многих описанных в статье трюков нужен root и зависящий от него . В стандартном варианте он будет на 100% корректно работать только в AOSP-прошивках, но даже в них могут встретиться глюки. Проблемы с Xposed-модулями часто могут возникать в стоковых прошивках с модификациями от производителя, но для них есть специальная версия Xposed: для TouchWiz , для MIUI , для прошивок на базе Android 5.0+ . Владельцы HTC могут устанавливать официальную сборку, но почти всегда требуется S-OFF.

Получил root, установил Xposed? Тогда поехали.

1. МЕНЯЕМ АНИМАЦИЮ ЗАГРУЗКИ

Анимация загрузки хранится в файле /system/media/bootanimation.zip. Внутри содержится текстовый документ desc.txt, в нем указаны частота смены кадров, разрешение по горизонтали и вертикали и прочее. Там же лежат сами изображения (кадры), которые меняются с частотой, указанной в desc.txt. Порядок и правила воспроизведения анимации из папок тоже прописаны в этом файле.

Все, что тебе нужно сделать, - достать архив с устройства при помощи файлового менеджера с поддержкой root, распаковать и заменить изображения, не забыв их предварительно пережать в нужном разрешении. Далее достаточно запаковать архив без сжатия и вернуть на место. Но, конечно же, проще взять уже готовый архив. На сайте hboot.co.uk таких полно.

С другой стороны, смотреть на анимацию хоть и интересно, но смысла никакого. А вот видеть, какие службы запускаются, бывает полезно. Самый простой вариант - установить LiveBoot , который выводит logcat и dmesg, то есть сообщения Android и ядра Linux.

2. ДОБАВЛЯЕМ СВОИ ЗВУКИ В СТАНДАРТНЫЙ НАБОР

Звуки можно скидывать в одну из папок в /system/media/audio. alarms - мелодии для будильника;
notifications - звуки для уведомлений;
ringtones - мелодии звонка;
ui - системные звуки, например низкий заряд батареи, фокусировка камеры, выбор элементов интерфейса. Некоторые приложения могут обращаться к ним по умолчанию, следовательно, их можно заменить на свои.

Зачем складывать мелодии в системный раздел? Во-первых, файлы там способны выдержать общий сброс к заводским настройкам; во-вторых, звуки из специальных папок можно поставить на сигнал (звук будильника, звонок, получение СМС) практически в любом приложении.

3. МЕНЯЕМ ШРИФТЫ

В полезности этих действий я очень и очень сомневаюсь, потому что стандартный шрифт Android почти идеален. Но на вкус и цвет…

Для установки шрифтов можно использовать специальное приложение. Например, HiFont позволяет без root менять шрифты в прошивках Samsung, HTC, Motorola, Lenovo, Huawei, Nokia X. А если есть root, то и во всех остальных устройствах. Можно как использовать уже имеющиеся в каталоге приложения шрифты, так и добавить свои.

Но где их брать? Есть три варианта:

  • шрифты, выдранные из разных прошивок Android-устройств, можно найти в посте на 4PDA ;
  • на 4PDA же есть неплохая коллекция шрифтов, созданных пользователями, в соседнем посте ;
  • коллекция на XDA .

Установить шрифты можно и без использования специального приложения. Берем из архива файлы.ttf, кидаем их с заменой в /system/fonts/ (нужен root) и перезагружаем устройство.

4. МЕНЯЕМ ИКОНКИ

Иконки можно менять с помощью специальных приложений, например Unicon - Icon Themer. После установки необходимо активировать приложение в настройках Xposed (он сам тебя уведомит). Далее перезагружаем смартфон и открываем приложение. Осталось нажать на Download themes from Google Play и выбрать пакет иконок, установить его и перезагрузить смартфон. Но стоит учитывать, что иконки не меняются в некоторых лаунчерах, например Google Старт.

5. ДОБАВЛЯЕМ ПОДДЕРЖКУ ТЕМ

Перед установкой темы HKThemeManager покажет весь список приложений, к которым будет применена тема. Убираем галочки с тех, что не нужны, нажимаем на «Применить тему» и перезагружаем устройство.

Есть и альтернативный вариант установки тем - приложение Layers Manager . Оно работает в любой прошивке на Android 5.0+ благодаря появлению механизма переназначения ресурсов RRO. База тем у приложения огромна и находится на Play Market. Чтобы посмотреть ее, достаточно набрать в поиске Layers Theme.

Имей в виду, что приложение не работает на прошивках, основанных на CyanogenMod: тамошний движок и RRO конфликтуют.

6. ПРЕВРАЩАЕМ ANDROID 5.X+ В ANDROID N

В этом нам поможет модуль Android N-ify . После установки появятся следующие фишки из Android N:

  • дизайн панели уведомлений заметно преобразится. Появится панель быстрых настроек;
  • в настройках под некоторыми пунктами возникнут интересные надписи.
  • К примеру, под Wi-Fi будет написано название текущей точки доступа, под пунктом «Батарея» - оставшееся время работы и заряд аккумулятора в процентах;
  • в меню «О телефоне» поменяется пасхалка;
  • появится быстрое переключение между двумя последними запущенными приложениями с помощью двойного нажатия на кнопку «Недавние».

Есть у Android N-ify и полезные настройки, через которые можно не только отключить, но и настроить отдельные вносимые изменения.

7. УЛУЧШАЕМ СТРОКУ СОСТОЯНИЯ

Для меня строка состояния в стоковом Android - самая недоработанная штука. К счастью, с помощью Xposed можно многое изменить и сделать ее более удобной.

8. Меняем индикатор батареи

Battery Home Icon устанавливает индикатор батареи вместо кнопки «Домой». Причем этот индикатор хорошо поддается настройке: можно менять цвета, включать/отключать показ процентов, анимацию зарядки и так далее.

XbatteryThemer - настройка значка батареи. Присутствует много различных тем, как обычных, так и очень неординарных.

9. Выводим скорость интернет-соединения

Network Speed Indicator - индикатор скорости сети. Умеет показывать скорость мобильных сетей, Wi-Fi, Bluetooth, Ethernet. Настраивается все - от единиц измерения и порога скорости до цвета и размера шрифта. Также можно добавить в строку состояния количество использованного интернет-трафика с помощью DataUsage . Данные показываются те же, что и в разделе настроек «Передача данных».

10. Выводим реальный уровень сигнала

Иногда нужно знать, насколько хорошо ловит интернет в разных частях комнаты, как влияет положение смартфона на уровень приема сигнала, или просто необходимо сравнить уровень приема сигнала твоего смартфона и других моделей. В этом поможет NetStrength . Модуль умеет выводить уровень сигнала сотовой сети в децибелах к милливатту (дБм или dBm). Эта единица измерения имеет отрицательное значение, и чем оно ближе к нулю, тем лучше прием. Можно также включить показ ASU (Arbitrary Strength Unit - отношение сигнал/ шум в пилотном канале). Вычисляется по формуле ASU = (dBm + 113)/2.

Кстати, модуль умеет показывать уровень приема Wi-Fi в dBm, Mbps (Мбит/с - мегабит в секунду) и процентах.

11. Следим за процессом загрузки

Statusbar Download Progress - один из самых полезных модулей Xposed. Он выводит процесс загрузки из Play Market или файла из интернета в виде тонкой белой полосы над строкой состояния. Сразу рекомендую активировать «Режим бога», благодаря которому прогресс будет отображаться для любых приложений, имеющих индикатор выполнения. В настройках можно поставить отображение над строкой состояния или под строкой.

Итак, давайте сегодня создадим простое меню, для приложения на Android. Создадим новый проект. Назовем его Mymenu, нажмем next. Выберем Empty Activity. Нажмем finish.

Система Android studio подготовит нам новый проект, перейдем в gradle скрипы. В Build gradle, добавим новую имплементацию. Нам понадобятся пакет

implementation "com.android.support:design:26.0.0-beta1"

По крайней мере, в моем проекте. Нажмем синхронизировать проект.

Пункты меню

Перейдем в папку Res и создадим в ней новую Andriod ресурсную папку с ресурсным типом - меню. В ней же, создадим новый ресурс файл меню. Имя файлу присвоим, как и имя папки - menu.

На наше основное меню перетаскиванием, добавим MenuItem в количестве 3 штук.

В файле strings.xml напишем новые название, для пунктов меню, создав дополнительные строковые значение для них.

Пусть item1 будет Пункт 1, item2 Пункт 2, и item3 пусть будет Выход.

Пункт 1 Пункт 2 Выход

В текстовом варианте menu.xml присвоим названия из strings.xml для наших пунктов. Также для каждого item мы добавим, Android:id с именем action1, action2,action3,

для взаимодействия с данными пунктами. Действие номер 1 будет отвечать за что-то, какая то реакция, нажатие пункта Action 2, соответственно, будет отвечать за другие действие, Action 3 будет отвечать за выход из приложения.

В файле MainActivity напишем несколько функций для работы с меню:

onCreateOptionsMenu @Override public boolean onCreateOptionsMenu(Menu menu){ getMenuInflater().inflate(R.menu.menu, menu); return true; } onOptionsItemSelected @Override public boolean onOptionsItemSelected(MenuItem item){ int id = item.getItemId(); switch (id){ case R.id.action1: txt.setText(R.string.item1); return true; case R.id.action2: txt.setText(R.string.item2); return true; case R.id.action3: txt.setText(R.string.item3); finish(); return true; } return super.onOptionsItemSelected(item); }

Объявим переменную типа TextView txt, и свяжем ее с элементом TextView, в onCreate через

txt=(TextView)findViewById(R.id.txt),

в макете activity_main.xml, добавив ему

android:id="@+id/txt"

для отображения текста.

Запустим в эмуляторе наше приложение. Как видим, появляются пункты меню, при нажатии на значение Пункт 1 или 2, текст меняется на Пункт 1 или Пункт 2, при нажатии на кнопку Выход появляется текст Выход и приложение закрывается.

Верстка меню

Кажется, все хорошо. Однако, как всегда в Android Studio данное меню будет работать только на эмуляторе, и поэтому добавим в файл styles.xml небольшой код, а перед этим в AndroidManifest.xml изменим

android:theme="@style/AppTheme"

android:theme="@style/AppTheme.NoActionBar"

который говорит о том, что новый стиль без ActionBar. Также в MainActivity onCreate внесем переменную toolbar c типом ToolBar. Определим ее через toolbar = (Toolbar)findViewById(R.id.toolbar), и подключим поддержку setSupportActionBar(toolbar).

В макет activity_main.xml перед TextView добавим следующий код:

Подключим эти виджеты в импорт нашего приложения.

import android.support.v7.widget.Toolbar;

Нажмем Alt+Enter, и у нас добавится, обновится импорт нашего приложения. Возможно, придется сделать несколько раз для подключения виджета. Нажмем Сохранить.

Теперь мы можем запустить наше приложение в эмуляторе. Все выглядит точно также, но без данного кода, наше приложение не может быть установлено на реальное устройство. Давайте сделаем подписанное приложение.

Создание меню

Последнее обновление: 26.02.2017

Меню в приложениях представляет класс android.view.Menu , и каждая activity ассоциируется с объектом этого типа. Объект android.view.Menu может включать различное количество элементов, а те в свою очередь могут хранить подэлементы.

Определение меню в xml

Меню, как и файлы интерфейса или изображений, также представляет собой ресурс. По умолчанию файлы меню находятся в проекте в каталоге res/menu .

При создании нового проекта с Empty Activity у нас нет никакого каталога res/menu и соответственно нет ресурсов меню, но мы можем их добавить вручную. Для этого нажмем правой кнопкой мыши в проекте на каталог res и далее в открывшемся списоке выберем пункт New -> Android Resource File :

После этого в каталоге res будет создан подкаталог menu, в котором будет находиться файл main_menu.xml.

По умолчанию этот файл определяет один пустой элемент menu:

Изменим содержимое файла, определив несколько пунктов:

Тег

является корневым узлом файла и определяет меню, состоящее из одного или нескольких элементов и .

Элемент представляет объект MenuItem, которой является одним из элементов меню. Этот элемент может содержать внутренний подэлемент

, с помощью которого создается подменю.

Элемент включает следующие атрибуты, которые определяют его внешний вид и поведение:

    android:id : уникальный id элемента меню, который позволяет его опознать при выборе пользователем и найти через поиск ресурса по id

    android:orderInCategory : порядок следования элемента в меню

Наполнение меню элементами

Мы определили меню с тремя элементами, но само определение элементов в файле еще не создает меню. Это всего лишь декларативное описание. Чтобы вывести его на экран, нам надо использовать его в классе Activity. Для этого надо переопределить метод onCreateOptionsMenu . Итак, перейдем к классу MainActivity и изменим его следующим образом:

Package com.example.eugene.menuapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } }

Метод getMenuInflater получает объект MenuInflater и вызываем его метод inflate() . Этот метод в качестве первого параметра принимает ресурс, представляющий наше декларативное описание меню в xml, и наполняет им объект menu, переданный в качестве второго параметра.

Запустим приложение по умолчанию и нажмем на кнопку меню в правом верхнем углу:

Обработка нажатий в меню

Если мы нажмем на любой из пунктов меню, то ничего не произойдет. Чтобы привязать к меню действия, нам надо переопределить в классе activity onOptionsItemSelected .

Для вывода выбранного элемена меню в файле activity_main.xml определим текстовое поле с id=header:

И изменим класс MainActivity:

Package com.example.eugene.menuapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); TextView headerView = (TextView) findViewById(R.id.header); switch(id){ case R.id.action_settings: headerView.setText("Настройки"); return true; case R.id.open_settings: headerView.setText("Открыть"); return true; case R.id.save_settings: headerView.setText("Сохранить"); return true; } return super.onOptionsItemSelected(item); } }

Чтобы понять, какой пункт меню выбран, вначале получаем его идентификатор int id = item.getItemId() . Затем пробегаемся в конструкции switch..case и выбираем нужный вариант и в зависимости от выбора производим определенные действия - в данном случае устанавливаем текст TextView.

Первого месяца обучения. Рассмотрим работу с меню глубже. Будут рассмотрены как старые устройства под Android 2.3, так и новые телефоны на Android 4.0.

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

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

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

Когда меню открывается впервые, 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 на устройстве:

@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.game_menu, menu); return true; }

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

Import android.view.Menu; import android.view.MenuInflater;

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

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

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

Как видите, меню появляется в нижней части экрана. Всего можно одновременно вывести на экран шесть пунктов меню. Если пунктов больше, то будет выведено пять пунктов плюс шестой пункт More , который позволит увидеть остальные пункты. Давайте проверим и добавим новые пункты меню.

Сначала добавим шесть пунктов.

Добавим еще один пункт к меню, чтобы их стало семь.

Выбор пунктов меню

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

@Override public boolean onOptionsItemSelected(MenuItem item) { // Операции для выбранного пункта меню switch (item.getItemId()) { case R.id.new_game: newGame(); return true; case R.id.help: showHelp(); return true; default: return super.onOptionsItemSelected(item); } } public void newGame() { edtext.setText("Выбран пункт Новая игра"); } public void showHelp() { edtext.setText("Выбран пункт Справка"); }

Запустите приложение, вызовите меню и выберите первый или второй пункт меню. В текстовом поле должно появиться сообщение.

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

В Android 3.0 можно добавить атрибут android:onClick в ресурсах меню, и вам уже не нужно использовать onOptionsItemSelected() . При помощи android:onClick вы можете указать нужный метод при выборе пункта меню.

// у атрибута пункта меню установлено значение android:onClick="onMenuClick" public void onMenuClick(MenuItem item){ edtext.setText("Выбран пункт Накормить кота"); }

Программное создание меню

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

// идентификаторы для пунктов меню private static final int IDM_OPEN = 101; private static final int IDM_SAVE = 102; public boolean onCreateOptionsMenu(Menu menu) { // добавляем пункты меню menu.add(Menu.NONE, IDM_OPEN, Menu.NONE, "Открыть"); menu.add(Menu.NONE, IDM_SAVE, Menu.NONE, "Сохранить"); }

У метода add() есть четыре параметра:

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

Метод возвращает объект MenuItem , который можно использовать для установки дополнительных свойств, например, для установить значок, горячую клавишу и т.д.

Если вы хотите создать меню со значками, то воспользуйтесь методом setIcon()

Menu.add(Menu.NONE, IDM_OPEN, Menu.NONE, "Открыть") .setIcon(R.drawable.icon_menu_open);

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

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

При выборе пункта меню вызывается метод onOptionsItemSelected , который передает объект MenuItem - пункт меню, выбранный пользователем. При помощи метода getItemId можно получить идентификатор выбранного пункта меню. После идентификации пункта меню можно написать код для обработки события выбора меню:

Public boolean onOptionsItemSelected(MenuItem item) { switсh (item.getItemId()) case IDM_OPEN: return true; case IDM_SAVE: return true; return false; }

Горячие клавиши

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

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

Например, если задать горячую клавишу setAlphabeticShortcut("q");, то при открытии меню (или при удерживании клавиши MENU) нажатие клавиши Q выберет данный пункт меню. Эта горячая клавиша (или сочетание клавиш) будет показана как подсказка, отображающая ниже имени пункта меню. В новых клавиатурах есть отдельная клавиша Ctrl , которая работает также, как на обычных клавиатурах.

Горячие клавиши можно создать и через XML: android:alphabeticShortcut="c" .

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

@Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_R: Toast.makeText(this, "Reply", Toast.LENGTH_SHORT).show(); return true; default: return super.onKeyShortcut(keyCode, event); } }

Создание подменю

Подменю можно добавить в любое меню, кроме другого подменю. Подменю создается в методе обратного вызова onCreateOptionsMenu() с помощью метода addSubMenu() , который возвращает объект SubMenu . В объект SubMenu можно добавить дополнительные пункты к этому меню, используя метод add() . Например:

Public static final int IDM_HELP = 101; public static final int IDM_NEW = 201; public static final int IDM_OPEN = 202; public static final int IDM_SAVE = 203; public static final int IDM_CUT = 301; public static final int IDM_COPY = 302; public static final int IDM_PASTE = 303; @Override public boolean onCreateOptionsMenu(Menu menu) { SubMenu subMenuFile = menu.addSubMenu("Файл"); subMenuFile.add(Menu.NONE, IDM_NEW, Menu.NONE, "Новый"); subMenuFile.add(Menu.NONE, IDM_OPEN, Menu.NONE, "Открыть"); subMenuFile.add(Menu.NONE, IDM_SAVE, Menu.NONE, "Сохранить"); SubMenu subMenuEdit = menu.addSubMenu("Правка"); subMenuEdit.add(Menu.NONE, IDM_CUT, Menu.NONE, "Вырезать"); subMenuEdit.add(Menu.NONE, IDM_COPY, Menu.NONE, "Копировать"); subMenuEdit.add(Menu.NONE, IDM_PASTE, Menu.NONE, "Вставить"); menu.add(Menu.NONE, IDM_HELP, Menu.NONE, "Справка"); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { CharSequence message; switch (item.getItemId()) { case IDM_NEW: message = "Выбран пункт Новый"; break; case IDM_OPEN: message = "Выбран пункт Открыть"; break; case IDM_SAVE: message = "Выбран пункт Сохранить"; break; case IDM_CUT: message = "Выбран пункт Вырезать"; break; case IDM_COPY: message = "Выбран пункт Копировать"; break; case IDM_PASTE: message = "Выбран пункт Вставить"; break; case IDM_HELP: message = "Выбран пункт Справка"; break; default: return false; } // выводим уведомление о выбранном пункте меню Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return true; }

Теперь при выборе пункта меню появится еще одно окно с подменю. Попробуйте сами.

Добавление флажков и переключателей

В пункты меню возможно добавление флажков или переключателей. Чтобы добавить флажок или переключатель для отдельного элемента меню, необходимо использовать метод setCheckable() :

MenuItem item = menu.add(0, IDM_FORMAT_BOLD, 0, "Bold"); item.setCheckable(true);

Если есть необходимость добавить несколько пунктов меню с флажками или переключателями, то можно объединить их в группы меню, создав отдельный идентификатор. Пункт меню добавляется в группу через метод add() , передав ему в качестве первого параметра идентификатор группы меню. Допустим, мы объявили идентификаторы для группы меню Цвет и элементов меню для установки цвета:

Public static final int IDM_COLOR_GROUP = 400; public static final int IDM_COLOR_RED = 401; public static final int IDM_COLOR_GREEN = 402; public static final int IDM_COLOR_BLUE = 403;

Теперь для создания группы меню с флажками нужно назначить идентификатор группы на каждый пункт меню и вызвать метод setGroupCheckable() для всей группы (этом случае нет необходимости вызывать метод setCheckable() для каждого пункта меню):

SubMenu subMenuColor = menu.addSubMenu("Цвет"); subMenuColor.add(IDM_COLOR_GROUP, IDM_COLOR_RED, Menu.NONE, "Красный"); subMenuColor.add(IDM_COLOR_GROUP, IDM_COLOR_GREEN, Menu.NONE,"Зеленый"); subMenuColor.add(IDM_COLOR_GROUP, IDM_COLOR_BLUE, Menu.NONE, "Синий"); subMenuColor.setGroupCheckable(IDM_COLOR_GROUP, true, false);

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

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

    Для управления состоянием флажков и переключателей в обработчике события выбора пункта меню нужно написать следующее:

    @Override public boolean onOptionsItemSelected(MenuItem item) { CharSequence message; switch (item.getItemId()) { ... case IDM_COLOR_RED: // инвертируем состояние флажка item.setChecked(!item.isChecked()); message = "Красный цвет"; break; default: return false; }

    Запустите проект, вызовите меню и выберите пункт меню Цвет . У вас появится подменю с тремя пунктами (Красный, Зеленый, Синий) в виде флажков. Состояние флажков и переключателей обрабатывается в коде программы и сохраняется при повторных вызовах меню.

    Можно сразу назначить намерение выбранному пункту меню через метод setIntent(), которое сработает при нажатии этого пункта, если данное событие не было перехвачено обработчиками onMenuItemClickListener (устар.) или onOptionsItemSelected. Сработав, намерение передается в метод startActivity.

    MenuItem.setIntent(new Intent(this, MyOtherActivity.class));

    Программное открытие или закрытие меню

    Если вам по каким-то причинам нужно программно открыть меню (например, в демонстрационных целях), то используйте метод openOptionsMenu() :

    OpenOptionsMenu();

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

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

    Допустим, мы определили пункт меню в xml-файле:

    Чтобы удалить явно лишний пункт меню из нашей программы о котах, нужно получить доступ к пункту меню через метод findItem() и сделать его невидимым. Ссылку на объект Menu нужно передать в метод onCreateOptionsMenu , чтобы программа узнала об изменении состава меню.

    // переменная класса Menu menu; @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // передаём ссылку на наш объект this.menu = menu; getMenuInflater().inflate(R.menu.test, menu); return true; } // щелчок кнопки public void onClick(View v) { if (menu != null) { // находим нужный элемент MenuItem item_dog = menu.findItem(R.id.action_dog); // делаем его невидимым item_dog.setVisible(false); } }

    Но у данного решения есть недостаток, если мы повернём экран, то активность пересоздатся и удалённое меню снова появится. Как же нам избавиться от сранного пёсика?

    Надо запомнить состояние пункта меню и сохранить его в объекте типа Bundle в методе onSaveInstanceState , а в методе onCreate() извлечь сохранённое состояние и передать методу onPrepareOptionsMenu , который вызывается перед показом меню на экране:

    Package ru.alexanderklimov.test; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; public class TestActivity extends Activity { Menu menu; Boolean savedMenuDogIsVisible; final static String KEY_MENU_DOG = "KEY_MENU_DOG"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); // извлекаем данные о видимости пункта меню if (savedInstanceState != null) { savedMenuDogIsVisible = savedInstanceState.getBoolean(KEY_MENU_DOG, true); } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); this.menu = menu; getMenuInflater().inflate(R.menu.test, menu); return true; } public void onClick(View v) { if (menu != null) { MenuItem item_dog = menu.findItem(R.id.action_dog); // прячем пункт меню item_dog.setVisible(false); } } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); if (menu != null) { MenuItem item_dog = menu.findItem(R.id.action_dog); // сохраняем текущее состояние пункта меню - true или false outState.putBoolean(KEY_MENU_DOG, item_dog.isVisible()); } } @Override public boolean onPrepareOptionsMenu(Menu menu) { if (savedMenuDogIsVisible != null) { MenuItem item_dog = menu.findItem(R.id.action_dog); // перед выводом на экран узнаём нужное состоятние пункта меню item_dog.setVisible(savedMenuDogIsVisible); } return super.onPrepareOptionsMenu(menu); } }

    Определить наличие кнопки Menu

    На старых устройствах использовалась реальная кнопка Menu. В новых версиях Android меню убрали в ActionBar и её наличие в виде отдельной кнопки стало необязательным. Но многие производители по-прежнему выпускают телефоны с кнопкой для меню. Чтобы определить, есть ли такая кнопка, в Android 14 добавили новый метод, который позволит определить наличие этой кнопки.

    If (Build.VERSION.SDK_INT <= 10 || (Build.VERSION.SDK_INT >= 14 && ViewConfiguration.get(this) .hasPermanentMenuKey())) { // menu key is present Toast.makeText(this, "Кнопка Menu есть", Toast.LENGTH_LONG).show(); } else { // No menu key Toast.makeText(this, "Кнопки Menu нет", Toast.LENGTH_LONG).show(); }

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

    В современных устройствах меню является частью ActionBar . И вы можете настроить разметку меню через XML.

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

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

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

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

    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.fragment_crime_list, menu); }

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

    // В коде фрагмента @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); getActivity().setTitle(R.string.cat); ... }

 
Статьи по теме:
Как сделать удобной работу с большим количеством вкладок в браузере
Вы сможете работать за компьютером быстрее, если оптимально расположите окна и вкладки браузера. Как быстро переключаться между окнами Нажмите и удерживайте клавишу Alt . Затем нажмите и удерживайте Tab , пока не откроется нужное окно. Как просматривать д
Установка и удаление AVG Internet Security Антивирус авг как включить компонент программы
В этом уроке мы рассмотрим, как установить бесплатный антивирус AVG. Почему именно бесплатный? Этот и другие вопросы я подробно опишу ниже! Сегодня проводить время в Интернете без защиты очень опасно, особенно новичку. Под защитой я подразумеваю антивир
Проверенные безопасные способы
С целью заработка в интернете многие пользователи запускают каналы на Ютубе. Идея хорошая, только без качественных роликов и грамотной раскрутки, никогда не получится зарабатывать большие деньги. Контент играет ключевую роль, а публикуя
Сервисы распознования капчи Автоматическое распознавание капчи
Здравствуйте, уважаемые читатели блога сайт. Антикапча (временно это был Антигейт) – это многофункциональная площадка для автоматического распознавания так называемой капчи (защиты от автоматического постинга ботами, а также защиты поисковиков от парсинг