- Контекстное меню и подменю
- Программное создание контекстного меню
- Контекстное меню через ресурсы
- Полный список
- Урок 15. Контекстное меню
- Android Lesson 12. Контекстное меню.
- Тайны кнопок в Android. Часть 3: Кнопки в главном меню
- Наша первая кнопка в меню
- Иконки для меню
- Подключение меню к Activity
- Создаем подменю
- Radio button’ы в меню
- Скрываем или показываем элементы меню
- Другие способы кастомизации меню
Контекстное меню и подменю
Кроме стандартного меню в Android используется также контекстное меню, вызываемое при нажатии на объект в течение двух-трёх секунд (событие long-press). Также на некоторых моделях устройств контекстное меню можно вызвать при нажатии трекбола или средней кнопки манипулятора D-pad. В отличие от обычного меню, в контекстном меню не поддерживаются значки и быстрые клавиши. Второе важно отличие — контекстное меню применимо к компоненту, а меню к активности. Поэтому в приложении может быть одно меню и несколько контекстных меню, например, у каждого элемента TextView.
Программное создание контекстного меню
Для создания контекстного меню используется метод обратного вызова onCreateContextMenu(). В данный метод можно добавлять пункты меню при помощи методов add(). C помощью метода onContextItemSelected() можно обрабатывать выбор пункта. Но сначала надо зарегистрировать контекстное меню для нужного объекта, например, для TextView при помощи метода registerForContextMenu().
Если запустить проект, то уже сейчас можно увидеть контекстное меню, которое пока не будет реагировать на выбранные пункты меню.
Допишем код для выбранного пункта меню.
Контекстное меню через ресурсы
Если вам нужно создать локализованный продукт, то программное добавление пунктов контекстного меню не подойдёт. В таких случаях используется традиционный способ через файл ресурсов, рекомендованный Google.
Создадим XML-файл res/menu/context_menu.xml для меню, а также добавим в разметку ещё один TextView:
Добавляем код к существующему.
Мы используем похожий код, как и при создании стандартного меню. В результате получим контекстное меню, созданное из ресурсов. При выборе нужного пункта изменится либо цвет, либо размер шрифта в TextView.
Источник
Полный список
В этом уроке мы:
— создадим контекстное меню
Контекстное меню вызывается в Андроид длительным нажатием на каком-либо экранном компоненте. Обычно оно используется в списках, когда на экран выводится список однородных объектов (например письма в почт.ящике) и, чтобы выполнить действие с одним из этих объектов, мы вызываем контекстное меню для него. Но т.к. списки мы еще не проходили, сделаем пример попроще и будем вызывать контекстное меню для TextView.
Project name: P0151_ContextMenu
Build Target: Android 2.3.3
Application name: ContextMenu
Package name: ru.startandroid.develop.contextmenu
Create Activity: MainActivity
Откроем main.xml и нарисуем там два TextView:
Для первого TextView мы сделаем контекстное меню, с помощью которого будем менять цвет текста. Для второго – будем менять размер текста.
Принцип создания контекстного меню похож на создание обычного меню. Но есть и отличия.
Метод создания onCreateContextMenu вызывается каждый раз перед показом меню. На вход ему передается:
— ContextMenu, в который мы будем добавлять пункты
— View — элемент экрана, для которого вызвано контекстное меню
— ContextMenu.ContextMenuInfo – содержит доп.информацию, когда контекстное меню вызвано для элемента списка. Пока мы это не используем, но, когда будем изучать списки, увидим, что штука полезная.
Метод обработки onContextItemSelected аналогичный методу onOptionsItemSelected для обычного меню. На вход передается MenuItem – пункт меню, который был нажат.
Также нам понадобится третий метод registerForContextMenu. На вход ему передается View и это означает, что для этой View необходимо создавать контекстное меню. Если не выполнить этот метод, контекстное меню для View создаваться не будет.
Давайте кодить, открываем MainActivity.java. Опишем и найдем TextView и укажем, что необходимо создавать для них контекстное меню.
Теперь опишем создание контекстных меню. Используем константы для хранения ID пунктов меню.
Обратите внимание, что мы по ID определяем View, для которого вызвано контекстное меню и в зависимости от этого создаем определенное меню. Т.е. если контекстное меню вызвано для tvColor, то мы создаем меню с перечислением цветов, а если для tvSize – с размерами шрифта.
В качестве ID пунктов мы использовали константы. Группировку и сортировку не используем, поэтому используем нули в качестве соответствующих параметров.
Можно все сохранить и запустить. При долгом нажатии на TextView должны появляться контекстные меню.
Но нажатие на них ничего не дает, т.к. мы не прописали обработку в методе onContextItemSelected. Давайте пропишем:
В этом методе мы определяем по ID, какой пункт меню был нажат. И выполняем соответствующие действия: меняем цвет текста для tvColor или размер шрифта для tvSize. Сохраняем, запускаем и проверяем, что контекстные меню теперь реагируют на нажатия и делают то, что от них требуется.
Для расширения кругозора я хотел бы еще кое-что написать по этой теме. Возможно, это покажется пока сложноватым, так что если вдруг будет непонятно, ничего страшного. Итак, мысли вслух.
Мы использовали метод registerForContextMenu (View view) для включения контекстного меню для определенного View. Этот метод принадлежит классу Activity. Я посмотрел исходники этого метода, там написано следующее:
Вспоминаем наш урок по обработчикам и смотрим хелп по методу setOnCreateContextMenuListener (View.OnCreateContextMenuListener l). Получается, что View в качестве обработчика создания контекстного меню использует объект this. В данном случае, этот код в Activity, значит this – это Activity и есть. Т.е. когда View хочет показать контекстное меню, оно обращается к обработчику (Activity), а он уже выполняет свой метод onCreateContextMenu. Т.е. тот же самый принцип, что и при обычном нажатии (Click).
И строка в MainActivity.java:
абсолютно равнозначна этой строке:
Вообще мы можем создать свой объект, реализующий интерфейс View.OnCreateContextMenuListener и использовать его вместо Activity в качестве обработчика создания контекстного меню.
Не забывайте, что для контекстного меню вы также можете использовать XML-способ, который был рассмотрен в конце прошлого урока. Попробуйте сделать этот же урок, но уже с использованием XML-меню.
Полный код урока:
На следующем уроке:
— рисуем экран программно, а не через layout-файл
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Урок 15. Контекстное меню
В этом уроке мы:
— создадим контекстное меню
Контекстное меню вызывается в Андроид длительным нажатием на каком-либо экранном компоненте. Обычно оно используется в списках. Когда на экран выводится список однородных объектов (например письма в почт.ящике) и, чтобы выполнить действие с одним из этих объектов, мы вызываем контекстное меню для него. Но т.к. списки мы еще не проходили, сделаем пример попроще и будем вызывать контекстное меню для TextView.
Project name: P0151_ContextMenu
Build Target: Android 2.3.3
Application name: ContextMenu
Package name: ru.startandroid.develop.contextmenu
Create Activity: MainActivity
Откроем main.xml и нарисуем там два TextView:
version = «1.0» encoding = «utf-8» ?>
xmlns:android = «http://schemas.android.com/apk/res/android»
android:orientation = «vertical»
android:layout_width = «fill_parent»
android:layout_height = «fill_parent» >
android:layout_height = «wrap_content»
android:textSize = «26sp»
android:layout_width = «wrap_content»
android:id = «@+id/tvColor»
android:layout_marginBottom = «50dp»
android:layout_marginTop = «50dp»
android:text = «Text color» >
android:layout_width = «fill_parent»
android:layout_height = «wrap_content»
android:textSize = «22sp»
android:id = «@+id/tvSize»
android:text = «Text size» >
Для первого TextView мы сделаем контекстное меню, с помощью которого будем менять цвет текста. Для второго – будем менять размер текста.
Принцип создания контекстного меню похож на создание обычного меню. Но есть и отличия.
Метод создания onCreateContextMenu вызывается каждый раз перед показом меню. На вход ему передается:
— ContextMenu, в который мы будем добавлять пункты
— View — элемент экрана, для которого вызвано контекстное меню
— ContextMenu.ContextMenuInfo – содержит доп.информацию, когда контекстное меню вызвано для элемента списка. Пока мы это не используем, но когда будем изучать списки увидим, что штука полезная.
Метод обработки onContextItemSelected аналогичный методу onOptionsItemSelected для обычного меню. На вход передается MenuItem – пункт меню, который был нажат.
Также нам понадобится третий метод registerForContextMenu. На вход ему передается View и это означает, что для этой View необходимо создавать контекстное меню. Если не выполнить этот метод, контекстное меню для View создаваться не будет.
Давайте кодить, открываем MainActivity.java. Опишем и найдем TextView и укажем, что необходимо создавать для них контекстное меню.
Теперь опишем создание контекстных меню. Используем константы для хранения ID пунктов меню.
Обратите внимание, что мы по ID определяем View, для которого вызвано контекстное меню и в зависимости от этого создаем определенное меню. Т.е. если контекстное меню вызвано для tvColor, то мы создаем меню с перечислением цветов, а если для tvSize – с размерами шрифта.
В качестве ID пунктов мы использовали константы. Группировку и сортировку не используем, поэтому используем нули в качестве соответствующих параметров.
Можно все сохранить и запустить. При долгом нажатии на TextView должны появляться контекстные меню.
Но нажатие на них ничего не дает, т.к. не мы не прописали обработку в методе onContextItemSelected. Давайте пропишем:
В этом методе мы определяем по ID, какой пункт меню был нажат. И выполняем соответствующие действия: меняем цвет текста для tvColor или размер шрифта для tvSize. Сохраняем, запускаем и проверяем, что контекстные меню теперь реагируют на нажатия и делают то, что от них требуется.
Для расширения кругозора я хотел бы еще кое-что написать по этой теме. Возможно, это покажется пока сложноватым, так что если вдруг будет непонятно, ничего страшного. Итак, мысли вслух.
Мы использовали метод registerForContextMenu (View view) для включения контекстного меню для определенного View. Этот метод принадлежит классу Activity. Я посмотрел исходники этого метода, там написано следующее:
Вспоминаем наш урок по обработчикам и смотрим хелп по методу setOnCreateContextMenuListener (View.OnCreateContextMenuListener l). Получается, что View в качестве обработчика создания контекстного меню использует объект this. В данном случае, этот код в Activity, значит this – это Activity и есть. Т.е. когда View хочет показать контекстное меню, оно обращается к обработчику (Activity), а он уже выполняет свой метод onCreateContextMenu. Т.е. тот же самый принцип, что и при обычном нажатии (Click).
И строка в MainActivity.java:
абсолютно равнозначна этой строке:
Вообще мы можем создать свой объект, реализующий интерфейс View.OnCreateContextMenuListener и использовать его вместо Activity в качестве обработчика создания контекстного меню.
Не забывайте, что для контекстного меню вы также можете использовать XML-способ, который был рассмотрен в конце прошлого урока. Попробуйте сделать этот же урок, но уже с использованием XML-меню.
Полный код урока:
На следующем уроке:
— рисуем экран программно, а не через layout-файл
Источник
Android Lesson 12. Контекстное меню.
В предыдущем примере мы работали со списком элементов. Если операцию в приложении нужно выполнить, учитывая сведения об ее окружении (контексте), то удобно воспользоваться контекстным меню. Контекстное меню появляется при длительном удерживании пальца на компоненте. Далее на экране появляется панель с возможными действиями, например удаление элемента или добавлением его в список избранного.
Создание контекстного меню очень похоже на создание обычного. Сначала мы определяем файл меню.
Содержимое list_item_context.xml.
Затем пользуемся методом onCreateContextMenu().
В нем мы все также вызываем метод inflate() класса MenuInflater для заполнения объекта ContextMenu. Для обработки нажатий на элементы контекстного меню существует метод onContextItemSelected().
Здесь мы в операторе switch проверяем, какой из элементов был нажат и выполняем соответствующие действия. В тестовом примере вместо выполнения реальных действий выводим на экран всплывающее сообщение с информацией о том, какой пункт меню был выбран.
Но если запустить приложение сейчас, то ничего не заработает. Почему? Контекстное меню необходимо зарегистрировать для того компонента, для которого оно создано. Например, это ListView из прошлого урока. Вызываем метод registerForContextMenu(View v):
Источник
Тайны кнопок в Android. Часть 3: Кнопки в главном меню
Главное меню — один из основных инструментов для взаимодействия пользователя с приложением. В Android 2.3.x и раньше оно было «спрятано» на аппаратной кнопке Menu, и разработчики рисовали меню кто как умел. Но начиная с Android 3.0 недоработка была исправлена, меню стало стандартным компонентом на Action Bar, и получило ряд новых возможностей. При этом процесс разработки меню практически не претерпел изменений. Меню в Android — это не просто набор кнопок, на которые можно вешать OnClickListener . В Android с меню можно сделать куда больше, чем кажется на первый взгляд.
В этой статье я расскажу, как сделать современное меню, как адаптировать его для разных размеров экрана, как делать переключатели типа radio button прямо в меню, а также как динамически управлять видимостью кнопок меню, скрывая те функции вашего приложения, которые не будут работать на том или ином смартфоне. По ходу статьи постараюсь дать максимально подробное описание тех или иных возможностей меню, а также дам ссылки на официальную документацию по теме.
Вот так по-разному может выглядеть меню одного и того же приложения.
Наша первая кнопка в меню
Меню в Android описываются в файлах ресурсов или формируются программным кодом. Рекомендуется первый вариант по целому ряду причин: скорость разработки, наглядность, простота сопровождения. Ресурсы меню располагаются в подкаталоге menu каталога ресурсов приложения res . Создаем каталог menu , затем создаем новый Android XML File :
Выбираем тип ресурса Menu , вводим имя файла. Так как в разных activity меню, скорее всего, будет разным, рекомендую привязывать имена файлов ресурсов меню к именам activity.
В открывшемся редакторе введем код первой кнопки нашего меню:
Давайте рассмотрим использованные атрибуты:
- android:id указываем, чтобы потом в коде отличать одни кнопки от других.
- android:orderInCategory указывает порядок нашей кнопки относительно других. Указывайте порядок с шагом в 10 или 100, это позволит в будущем добавлять новые элементы в любое место, не перестраивая порядок остальных.
- android:showAsAction — самый интересный параметр, поскольку именно он управляет поведением элементов меню в разных ситуациях. Он может принимать целый ряд значений:
- ifRoom — Показывать элемент в action bar, только если для него достаточно места. Если места недостаточно, элемент будет автоматически скрыт в дополнительное меню (то, которое показано тремя точками друг над другом). Это лучший способ кастомизации меню в зависимости от размера экрана устройства. На больших экранах планшетов action bar будет заполнен кнопками, а на небольших телефонах будут показаны самые важные кнопки, в то время как до остальных тоже можно добраться, но только через дополнительное меню. Имейте в виду, что дополнительное меню отображается в action bar только на тех смартфонах, на которых нет аппаратной кнопки меню.
- withText — Рядом с иконкой кнопки будет показан текст, заданный свойством android:title . Этот параметр можно указывать в комбинации с другими, разделяя параметры знаком |
- never — Кнопка никогда не будет видна на action bar, даже если для нее есть место. К такой кнопке всегда придется добираться через дополнительное меню.
- always — Всегда показывать кнопку в action bar. Данным параметром нельзя злоупотреблять, так как на маленьких телефонах кнопки могут начать заползать на другие элементы action bar, например на заголовок приложения. Определите для каждой activity максимум одну самую важную кнопку, без которой никак нельзя, и отметьте always только у нее. Остальные (а по возможности все) должны быть ifRoom .
- collapseActionView — позволяет сделать кнопку, открывающую или скрывающую дополнительный элемент View в action bar. Например, можно задать такой параметр иконке поиска, по ее клику показывать прямо в action bar поле для ввода поискового запроса.
- android:title — определяет заголовок кнопки меню. Он может отображаться рядом с иконкой в action bar или же как название элемента в дополнительном меню.
- android:icon — иконка кнопки.
Иконки для меню
Если вы разрабатываете приложение в стиле Holo, вы можете использовать готовый набор иконок от Google, который доступен всем для загрузки с официального сайта совершенно бесплатно.
Набор иконок представлен отдельно для темной и отдельно для светлой темы Holo, а также для разных размеров экранов. Если вы не можете позволить себе дизайнера в команде, этот набор просто незаменим.
Подключение меню к Activity
Загрузить меню из ресурса очень быстро. Открываем код Activity и перекрываем метод onCreateOptionsMenu :
Теперь меню отображается, но при нажатии на кнопку ничего не происходит. Повесить обработчик на кнопку можно кодом или прямо в XML-ресурсе, задав в свойстве android:onClick имя метода-обработчика. Чтобы сделать то же самое кодом, нужно в Activity перекрыть метод onOptionsItemSelected :
Создаем подменю
Подменю полезно, когда мы хотим уточнить способ выполнения действия, представленного в action bar. К примеру, у нас есть список покупок и кнопка «Сортировка». По нажатию кнопки нужно выяснить, по какому параметру пользователь хочет отсортировать элементы списка: по категории товара, по названию или по порядку добавления в список. Посмотрим код подменю для такого случая:
Здесь мы объявили еще один тег внутри тега . Подменю представляет собой группу все тех же тегов , что позволяет при необходимости сделать подменю в подменю и так далее.
Radio button’ы в меню
Мы только что сделали меню для выбора порядка сортировки покупок. Было бы здорово показывать, какой способ сортировки используется в текущий момент. Список может быть отсортирован только одним из трех возможных способов, что отлично соответствует идее radio button. Чтобы сделать из нашего подменю набор radio button, достаточно тегу указать свойство android:checkableBehavior=»single» . Возможные значения android:checkableBehavior :
- single — выбор только одного из доступных элементов, наш случай
- all — выбор любого количества доступных элементов, аналог check box
- none — элементы группы являются обычными элементами меню, это значение по умолчанию
Полученный код меню:
Если запустить приложение и попробовать выбрать один из способов сортировки, ничего не произойдет. В меню не показано, что какой-то элемент выбран. Это придется сделать вручную вызовом item.setChecked(true);
Скрываем или показываем элементы меню
Скрывать элементы меню полезно, если телефон временно или в принципе не может выполнить какой-либо функционал. Например, у нас есть кнопки для отправки списка покупок через соц. сети, но если интернет сейчас не подключен, то отправить список не получится. Чтобы не расстраивать пользователя сообщениями об ошибке, можно скрыть неработающие в данный момент кнопки. Давайте добавим кнопку «Поделиться»:
Теперь во время создания меню в методе onCreateOptionsMenu проверим доступность сети, найдем нашу кнопку и установим ей видимость:
Так мы подстраиваем меню в момент создания activity. Этого достаточно для тех функций, которые требуют наличия определенного аппаратного обеспечения в телефоне (камера и т.п.). Но интернет может включиться в любое время, даже после старта activity. Также иногда возникает желание перестроить меню после каких-то действий пользователя в приложении. Перестроить меню предельно просто. Вызываем метод invalidateOptionsMenu() нашей activity. Это приведет к повторному вызову метода onCreateOptionsMenu перед следующей отрисовкой меню. Обратите внимание, что метод invalidateOptionsMenu был добавлен в API 11, поэтому для совместимости с Android 2.x нужно использовать такой вызов:
Класс android.support.v4.app.ActivityCompat можно найти в Support Package.
Другие способы кастомизации меню
Как вы знаете, в Android можно задавать разные ресурсы для различных размеров/ориентации/плотности экрана и в зависимости от других особенностей устройств. Это касается любых типов ресурсов, в том числе и меню. По умолчанию ресурсы меню загружаются из каталога /res/menu. Но вы можете создать каталог, например, /res/menu-sw600dp, и таким образом задать особую компоновку меню для устройств с минимальным размером экрана 600 dp по горизонтали или вертикали (это как правило соответствует 7-ми дюймовым планшетам). На практике для меню обычно достаточно указания свойства android:showAsAction=»ifRoom» для элементов, так как в результате мы получаем максимально точную «подгонку» меню к тому устройству, на котором будет работать приложение. К тому же это позволяет сильно уменьшить объем кода ресурсов, ведь их в этом случае не нужно дублировать.
Если у вас остались вопросы по работе с главным меню, буду рад ответить в комментариях.
Источник