1page.title=Меню 2parent.title=Пользовательский интерфейс 3parent.link=index.html 4@jd:body 5 6<div id="qv-wrapper"> 7<div id="qv"> 8 <h2>Содержание документа</h2> 9<ol> 10 <li><a href="#xml">Определение меню в файле XML</a></li> 11 <li><a href="#options-menu">Создание меню параметров</a> 12 <ol> 13 <li><a href="#RespondingOptionsMenu">Обработка нажатий</a></li> 14 <li><a href="#ChangingTheMenu">Изменение пунктов меню во время выполнения</a></li> 15 </ol> 16 </li> 17 <li><a href="#context-menu">Создание контекстного меню</a> 18 <ol> 19 <li><a href="#FloatingContextMenu">Создание плавающего контекстного меню</a></li> 20 <li><a href="#CAB">Использование режима контекстных действий</a></li> 21 </ol> 22 </li> 23 <li><a href="#PopupMenu">Создание всплывающего меню</a> 24 <ol> 25 <li><a href="#PopupEvents">Обработка нажатий</a></li> 26 </ol> 27 </li> 28 <li><a href="#groups">Создание групп меню</a> 29 <ol> 30 <li><a href="#checkable">Использование пунктов меню, которые можно пометить</a></li> 31 </ol> 32 </li> 33 <li><a href="#intents">Добавление пунктов меню на основе объектов Intent</a> 34 <ol> 35 <li><a href="#AllowingToAdd">Предоставление возможности добавить свою операцию в другие меню</a></li> 36 </ol> 37 </li> 38</ol> 39 40 <h2>Основные классы</h2> 41 <ol> 42 <li>{@link android.view.Menu}</li> 43 <li>{@link android.view.MenuItem}</li> 44 <li>{@link android.view.ContextMenu}</li> 45 <li>{@link android.view.ActionMode}</li> 46 </ol> 47 48 <h2>См. также</h2> 49 <ol> 50 <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Строка действий</a></li> 51 <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Ресурс меню</a></li> 52 <li><a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">Попрощайтесь 53с кнопкой "Меню"</a></li> 54 </ol> 55</div> 56</div> 57 58<p>Меню являются стандартным компонентом пользовательского интерфейса в приложениях многих типов. Для обеспечения привычной 59и единообразной технологии работы с приложением следует представлять действия пользователя и другие варианты выбора в своих операциях 60с помощью API-интерфейсов класса {@link android.view.Menu}.</p> 61 62<p>Начиная с версии Android 3.0 (уровень API 11) в устройствах, работающих под управлением Android, 63наличие отдельной кнопки <em>Меню</em> больше не требуется. С учетом этого изменения приложения для Android должны перестать 64зависеть от традиционной панели меню из 6 пунктов. Вместо нее в них должна быть строка действий с часто используемыми 65действиями пользователя.</p> 66 67<p>Несмотря на то что оформление и поведение некоторых пунктов меню изменились, семантика для определения 68набора действий и вариантов по-прежнему основана на API-интерфейсах класса {@link android.view.Menu}. В этом 69руководстве рассказывается, как создавать три основополагающих типа меню или представлений действий в системе 70Android всех версий:</p> 71 72<dl> 73 <dt><strong>Меню параметров и строка действий</strong></dt> 74 <dd>Пункты <a href="#options-menu">меню параметров</a> представляют собой основные варианты выбора действий в пределах 75операции. Именно здесь следует размещать действия, которые затрагивают приложение в целом, например: 76"Поиск", "Составить сообщение эл. почты" и "Настройки". 77 <p>При разработке приложений для версии Android 2.3 или более ранних версий пользователи могут 78открыть панель меню параметров нажатием кнопки <em>Меню</em>.</p> 79 <p>В версии Android 3.0 и последующих версиях пункты меню параметров размещаются в <a href="{@docRoot}guide/topics/ui/actionbar.html">строке действий</a> в виде сочетания отображаемых на экране вариантов 80действий и раскрывающегося списка дополнительных вариантов выбора. Начиная с Android 3.0 кнопка <em>Меню</em> больше не используется (на некоторых 81устройствах 82ее нет), поэтому для предоставления доступа к действиям и другим вариантам выбора вам следует перейти к использованию 83строки действий.</p> 84 <p>См. раздел <a href="#options-menu">Создание меню параметров</a></p> 85 </dd> 86 87 <dt><strong>Контекстное меню и режим контекстных действий</strong></dt> 88 89 <dd>Контекстное меню ― это <a href="#FloatingContextMenu">плавающее меню</a>, которое открывается, когда 90пользователь длительно нажимает на элемент. В нем содержатся действия, которые затрагивают выбранный контент или 91контекстный кадр. 92 <p>При разработке приложения для версии Android 3.0 или выше вместо этого для обеспечения действий с выбранным контентом следует использовать <a href="#CAB">режим контекстных действий</a>. В этом режиме 93в строке, расположенной вверху экрана, отображаются пункты действий, затрагивающие выбранный контент, причем пользователь может 94выбрать сразу несколько элементов.</p> 95 <p>См. раздел <a href="#context-menu">Создание контекстного меню</a></p> 96</dd> 97 98 <dt><strong>Всплывающее меню</strong></dt> 99 <dd>Во всплывающем меню отображается вертикальный список пунктов, который привязан к представлению, 100вызвавшему меню. Он хорошо подходит для предоставления возможности дополнительных вариантов действий, относящихся к определенному контенту или 101для выдачи вариантов для второй части команды. Действия во всплывающем меню 102<strong>не</strong> должны напрямую затрагивать соответствующий контент — для этого предназначены контекстные 103действия. Всплывающее меню предназначено для расширенных действий, относящихся к областям контента в вашей 104операции. 105 <p>См. раздел <a href="#PopupMenu">Создание всплывающего меню</a></p> 106</dd> 107</dl> 108 109 110 111<h2 id="xml">Определение меню в файле XML</h2> 112 113<p>Для определения пунктов меню всех типов в Android используется стандартный формат XML. 114Вместо того чтобы создавать меню в коде своей операции, определять меню и все его пункты следует в 115 <a href="{@docRoot}guide/topics/resources/menu-resource.html">ресурсе меню</a> формата XML. После этого 116ресурс меню можно будет загружать как объект {@link android.view.Menu} в свои операции или 117фрагменты.</p> 118 119<p>Использовать ресурсы меню рекомендуется по нескольким причинам:</p> 120<ul> 121 <li>в XML проще визуализировать структуру меню;</li> 122 <li>это позволяет отделить контент для меню от кода, определяющего работу приложения;</li> 123 <li>это позволяет создавать альтернативные варианты меню для разных версий платформы, 124размеров экрана и других конфигураций путем использования структуры <a href="{@docRoot}guide/topics/resources/index.html">ресурсов приложения</a>.</li> 125</ul> 126 127<p>Чтобы определить меню, создайте файл XML в папке <code>res/menu/</code> 128вашего проекта и постройте меню со следующими элементами:</p> 129<dl> 130 <dt><code><menu></code></dt> 131 <dd>Определяет класс {@link android.view.Menu}, который является контейнером для пунктов меню. Элемент 132<code><menu></code> должен быть корневым узлом файла, в котором может находиться один или несколько элементов 133<code><item></code> и <code><group></code>.</dd> 134 135 <dt><code><item></code></dt> 136 <dd>Создает класс {@link android.view.MenuItem}, который представляет один пункт меню. Этот 137элемент может содержать вложенный элемент <code><menu></code> для создания вложенных меню.</dd> 138 139 <dt><code><group></code></dt> 140 <dd>Необязательный, невидимый контейнер для элементов {@code <item>}. Он позволяет 141разделять пункты меню на категории и назначать им одинаковые свойства, такие как активное состояние и видимость. Подробные 142сведения изложены в разделе <a href="#groups">Создание групп меню</a>.</dd> 143</dl> 144 145 146<p>Вот пример меню с именем <code>game_menu.xml</code>:</p> 147<pre> 148<?xml version="1.0" encoding="utf-8"?> 149<menu xmlns:android="http://schemas.android.com/apk/res/android"> 150 <item android:id="@+id/new_game" 151 android:icon="@drawable/ic_new_game" 152 android:title="@string/new_game" 153 android:showAsAction="ifRoom"/> 154 <item android:id="@+id/help" 155 android:icon="@drawable/ic_help" 156 android:title="@string/help" /> 157</menu> 158</pre> 159 160<p>Элемент <code><item></code> поддерживает несколько атрибутов, с помощью которых можно определить внешний вид и 161поведение пункта меню. Пункты приведенного выше меню имеют следующие атрибуты:</p> 162 163<dl> 164 <dt>{@code android:id}</dt> 165 <dd>Идентификатор ресурса, который является уникальным для этого пункта, что позволяет приложению распознавать пункт, 166когда его выбирает пользователь.</dd> 167 <dt>{@code android:icon}</dt> 168 <dd>Ссылка на графический элемент, который будет использоваться в качестве значка пункта меню.</dd> 169 <dt>{@code android:title}</dt> 170 <dd>Ссылка на строку, которая будет использоваться в качестве названия пункта меню.</dd> 171 <dt>{@code android:showAsAction}</dt> 172 <dd>Указывает, когда и как этот пункт должен отображаться в <a href="{@docRoot}guide/topics/ui/actionbar.html">строке действий</a>.</dd> 173</dl> 174 175<p>Это самые важные атрибуты, которые следует использовать, но есть также множество других атрибутов. 176Сведения обо всех поддерживаемых атрибутах см. в документе <a href="{@docRoot}guide/topics/resources/menu-resource.html">Ресурс меню</a>.</p> 177 178<p>К пункту любого меню (кроме вложенного меню) можно прикрепить вложенное меню, добавив элемент {@code <menu>} 179в качестве дочернего элемента {@code <item>}. Вложенные меню полезны, когда в приложении имеется множество 180функций, которые можно разделить на категории подобно строке меню приложения для ПК ("Файл", 181"Правка", "Вид" и т. д.). Например:</p> 182 183<pre> 184<?xml version="1.0" encoding="utf-8"?> 185<menu xmlns:android="http://schemas.android.com/apk/res/android"> 186 <item android:id="@+id/file" 187 android:title="@string/file" > 188 <!-- "file" submenu --> 189 <menu> 190 <item android:id="@+id/create_new" 191 android:title="@string/create_new" /> 192 <item android:id="@+id/open" 193 android:title="@string/open" /> 194 </menu> 195 </item> 196</menu> 197</pre> 198 199<p>Для использования меню в операции необходимо загрузить ресурс меню (преобразовать ресурс XML 200в программируемый объект) с помощью метода {@link android.view.MenuInflater#inflate(int,Menu) 201MenuInflater.inflate()}. В приведенных далее разделах рассказывается, как загружать меню 202каждого типа.</p> 203 204 205 206<h2 id="options-menu">Создание меню параметров</h2> 207 208<div class="figure" style="width:200px;margin:0"> 209 <img src="{@docRoot}images/options_menu.png" height="333" alt="" /> 210 <p class="img-caption"><strong>Рисунок 1.</strong> Меню параметров в 211браузере на Android 2.3.</p> 212</div> 213 214<p>В меню параметров следует размещать действия и другие варианты выбора, которые имеют отношение к 215контексту текущей операции, например: "Поиск", "Составить сообщение эл. почты" и "Настройки".</p> 216 217<p>Место, где отображаются на экране пункты вашего меню параметров, определяется версией платформы, для которой 218разработано приложение.</p> 219 220<ul> 221 <li>Если приложение написано для версии <strong>Android 2.3.x (уровень API 10) или 222более ранней</strong>, содержимое вашего меню параметров отображается внизу экрана, когда пользователь 223нажимает кнопку <em>Меню</em>, как показано на рисунке 1. Когда меню открывается, первой видимой частью является меню 224значков, 225в котором имеется шесть пунктов. Если в вашем меню больше шести пунктов, система Android разместит 226шестой и остальные пункты в дополнительном меню, которое пользователь может открыть, выбрав вариант 227 <em>Еще</em>.</li> 228 229 <li>Если приложение предназначено для версии <strong>Android 3.0 (уровень API 11) и 230более поздних</strong>, пункты меню параметров будут отображаться в <a href="{@docRoot}guide/topics/ui/actionbar.html">строке действий</a>. По умолчанию система 231размещает все действия на панели дополнительных вариантов, которые пользователь может открыть с помощью значка дополнительных действий, расположенного 232с правой стороны строки действий (либо нажатием кнопки <em>Меню</em>, если на устройстве есть такая кнопка). Чтобы 233обеспечить 234быстрый доступ к важным действиям, можно принудительно разместить несколько пунктов меню в строке действий, добавив 235{@code android:showAsAction="ifRoom"} к соответствующим элементам {@code <item>} (см. рисунок 2362). <p>Подробные сведения о пунктах действий и других особенностях строки действий см. в руководстве <a href="{@docRoot}guide/topics/ui/actionbar.html">Строка действий</a>. </p> 237<p class="note"><strong>Примечание.</strong> Даже если ваше приложение <em>не</em> предназначено для работы в версии Android 3.0 или 238более поздней, можно создать собственный макет со строкой действий, чтобы реализовать похожий эффект. Пример того, как можно 239поддерживать работу строки действий в старых версиях Android см. в образце кода, иллюстрирующем 240 <a href="{@docRoot}resources/samples/ActionBarCompat/index.html">Совместимость строки действий</a>.</p> 241</li> 242</ul> 243 244<img src="{@docRoot}images/ui/actionbar.png" alt="" /> 245<p class="img-caption"><strong>Рисунок 2.</strong> Строка действий из приложения <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>, содержащая 246вкладки навигации и пункт включения камеры (а также кнопку открытия дополнительной панели действий).</p> 247 248<p>Объявлять пункты меню параметров можно либо из подкласса {@link android.app.Activity}, 249либо из подкласса {@link android.app.Fragment}. Если и ваша операция, и фрагменты 250объявляют пункты меню параметров, в пользовательском интерфейсе они объединяются. Сначала отображаются пункты 251операции, а за ними следуют пункты фрагментов в том порядке, в котором каждый фрагмент добавляется в 252операцию. При необходимости можно изменить порядок следования пунктов меню с помощью атрибута {@code android:orderInCategory}, 253указываемого в каждом {@code <item>}, который требуется переместить.</p> 254 255<p>Чтобы указать меню параметров для операции, переопределите {@link 256android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} (фрагменты предоставляют собственный обратный 257вызов {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}). В этом 258методе можно загрузить собственный ресурс меню (<a href="#xml">определенный в XML</a>) в класс {@link 259android.view.Menu}, имеющийся в обратном вызове. Например:</p> 260 261<pre> 262@Override 263public boolean onCreateOptionsMenu(Menu menu) { 264 MenuInflater inflater = {@link android.app.Activity#getMenuInflater()}; 265 inflater.inflate(R.menu.game_menu, menu); 266 return true; 267} 268</pre> 269 270<p>Пункты меню также можно добавлять с помощью {@link android.view.Menu#add(int,int,int,int) 271add()}, а получать их с помощью {@link android.view.Menu#findItem findItem()} для пересмотра их 272свойств с помощью API-интерфейсов {@link android.view.MenuItem}.</p> 273 274<p>Если ваше приложение предназначено для версии Android 2.3.x или более ранней, система вызывает метод {@link 275android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} для создания меню параметров, 276когда пользователь открывает это меню впервые. Если приложение предназначено для версии Android 3.0 и или более поздней, система 277вызывает метод{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} при 278запуске операции, чтобы отобразить пункты в строке действий.</p> 279 280 281 282<h3 id="RespondingOptionsMenu">Обработка нажатий</h3> 283 284<p>Когда пользователь выбирает пункт меню параметров (в том числе пункты действий из строки действий), 285система вызывает метод {@link android.app.Activity#onOptionsItemSelected(MenuItem) 286onOptionsItemSelected()} вашей операции. Этот метод передает выбранный класс {@link android.view.MenuItem}. Идентифицировать 287пункт меню можно, вызвав метод {@link android.view.MenuItem#getItemId()}, который возвращает уникальный 288идентификатор пункта меню (определенный атрибутом {@code android:id} из ресурса меню или 289целым числом, переданным методу {@link android.view.Menu#add(int,int,int,int) add()}). Этот идентификатор 290можно сопоставить с известными пунктами меню, чтобы выполнить соответствующее действие. Например:</p> 291 292<pre> 293@Override 294public boolean onOptionsItemSelected(MenuItem item) { 295 // Handle item selection 296 switch (item.getItemId()) { 297 case R.id.new_game: 298 newGame(); 299 return true; 300 case R.id.help: 301 showHelp(); 302 return true; 303 default: 304 return super.onOptionsItemSelected(item); 305 } 306} 307</pre> 308 309<p>Когда пункт меню успешно обработан, возвращается {@code true}. Если пункт меню не 310обрабатывается, следует вызвать реализацию суперкласса {@link 311android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} (реализация 312по умолчанию возвращает значение false).</p> 313 314<p>Если в вашей операции имеются фрагменты, система сначала вызовет метод {@link 315android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} для операции, а затем 316будет вызывать этот метод для каждого фрагмента (в том порядке, в котором они были добавлены), пока он не возвратит 317значение{@code true} или не закончатся фрагменты.</p> 318 319<p class="note"><strong>Совет.</strong> В Android 3.0 появилась возможность определять в XML поведение 320при нажатии для пунктов меню с помощью атрибута {@code android:onClick}. Значением этого 321атрибута должно быть имя метода, определенное операцией с помощью меню. Этот метод 322должен быть общедоступным и принимать один параметр {@link android.view.MenuItem}, — когда система 323вызывает этот метод, она передает ему выбранный пункт меню. Подробные сведения и пример см. в документе <a href="{@docRoot}guide/topics/resources/menu-resource.html">Ресурс меню</a>.</p> 324 325<p class="note"><strong>Совет.</strong> Если в приложении предусмотрено несколько операций и 326в некоторых из них имеются одинаковые меню параметров, рассмотрите возможность создания 327операции, которая будет использовать исключительно методы {@link android.app.Activity#onCreateOptionsMenu(Menu) 328onCreateOptionsMenu()} и {@link android.app.Activity#onOptionsItemSelected(MenuItem) 329onOptionsItemSelected()}. Затем распространите этот класс на все операции, у которых должно быть 330одинаковое меню параметров. Таким образом можно управлять одним набором кода для обработки действий 331меню, а каждый класс-потомок при этом будет наследовать режимы работы меню. 332Если требуется добавить пункты меню в одну из операций-потомков, 333переопределите метод {@link android.app.Activity#onCreateOptionsMenu(Menu) 334onCreateOptionsMenu()} в этой операции. Вызовите метод {@code super.onCreateOptionsMenu(menu)}, с тем чтобы 335создать первоначальные пункты меню, а затем добавьте новые пункты меню с помощью метода {@link 336android.view.Menu#add(int,int,int,int) menu.add()}. Также можно переопределять режимы работы 337суперкласса для отдельных пунктов меню.</p> 338 339 340<h3 id="ChangingTheMenu">Изменение пунктов меню во время выполнения</h3> 341 342<p>После того как система вызовет метод {@link android.app.Activity#onCreateOptionsMenu(Menu) 343onCreateOptionsMenu()}, она сохранит заполненный вами экземпляр {@link android.view.Menu} и 344будет вызывать метод {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} 345,только если меню по каким-то причинам станет некорректным. Однако метод {@link 346android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} следует использовать только для создания начального 347состояния меню, а не для внесения в него изменений в течение жизненного цикла операции.</p> 348 349<p>Если вам требуется изменять меню параметров в зависимости от 350событий, которые возникают в течение жизненного цикла операции, сделать это можно в 351методе{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}. Этот 352метод передает объект {@link android.view.Menu} в том виде, в котором он в данный момент существует. Его-то и можно изменить 353путем, например, добавления, удаления или отключения пунктов меню. (Фрагменты также предоставляют обратный вызов {@link 354android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()}.)</p> 355 356<p>В версии Android 2.3.x или более ранней система вызывает метод {@link 357android.app.Activity#onPrepareOptionsMenu(Menu) 358onPrepareOptionsMenu()} каждый раз, когда пользователь открывает меню параметров (нажимает кнопку <em>Меню</em> 359).</p> 360 361<p>В версии Android 3.0 и последующих версиях считается, что меню параметров всегда открыто, когда пункты меню 362приведены в строке действий. Когда возникает событие и требуется обновить меню, следует 363вызвать метод {@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()}, чтобы запросить у 364системы вызов метода {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}.</p> 365 366<p class="note"><strong>Примечание.</strong> 367Никогда не следует изменять пункты меню параметров с учетом класса {@link android.view.View}, действующего 368в данный момент. В сенсорном режиме (когда пользователь не использует трекбол или кнопки направления движения) фокус 369не может переводиться на представления, поэтому никогда не следует использовать фокус в качестве основы для изменения 370пунктов меню параметров. Если вы желаете предоставить пункты меню, которые зависят от контекста {@link 371android.view.View}, используйте <a href="#context-menu">контекстное меню</a>.</p> 372 373 374 375 376<h2 id="context-menu">Создание контекстного меню</h2> 377 378<div class="figure" style="width:420px;margin-top:-1em"> 379 <img src="{@docRoot}images/ui/menu-context.png" alt="" /> 380 <p class="img-caption"><strong>Рисунок 3</strong>. Снимки экрана с плавающим контекстным меню (слева) 381и строкой контекстных действий (справа).</p> 382</div> 383 384<p>В контекстном меню содержатся действия, которые затрагивают определенный элемент или контекстный кадр в пользовательском интерфейсе. Контекстное 385меню можно создать для любого представления, но чаще всего они используются для элементов из {@link 386android.widget.ListView}, {@link android.widget.GridView} или других групп представлений, в которых 387пользователь может выполнять действия непосредственно с каждым элементом.</p> 388 389<p>Существует два способа предоставления возможности контекстных действий:</p> 390<ul> 391 <li>В <a href="#FloatingContextMenu">плавающем контекстном меню</a>. Меню отображается в виде 392плавающего списка пунктов меню (наподобие диалогового окна), когда пользователь длительно нажимает на экран (нажимает и 393удерживает нажатым) в представлении, которое объявляет поддержку контекстного меню. Пользователи могут каждый раз выполнять контекстное 394действие только с одним элементом.</li> 395 396 <li>В <a href="#CAB">режиме контекстных действий</a>. Этот режим является системной реализацией 397{@link android.view.ActionMode}, которая отображает <em>строку контекстных действий</em> вверху 398экрана с пунктами действий, которые затрагивают выбранные элементы. Когда этот режим активен, пользователи 399могут одновременно выполнять действие с несколькими элементами (если это допускается приложением).</li> 400</ul> 401 402<p class="note"><strong>Примечание.</strong> Режим контекстных действий поддерживается в версии Android 3.0 (уровень API 40311) и последующих версиях. Если этот режим предусмотрен, именно его рекомендуется использовать для отображения контекстных 404действий. Если ваше приложение поддерживает версии ниже 3.0, то для этих устройств следует вернуться к плавающему 405контекстному меню.</p> 406 407 408<h3 id="FloatingContextMenu">Создание плавающего контекстного меню</h3> 409 410<p>Программирование плавающего контекстного меню</p> 411<ol> 412 <li>Зарегистрируйте класс {@link android.view.View}, с которым следует связать контекстное меню, 413вызвав метод {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} и передав 414ему {@link android.view.View}. 415 <p>Если операция использует {@link android.widget.ListView} или {@link android.widget.GridView} и 416требуется, чтобы каждый элемент предоставлял одинаковое контекстное меню, зарегистрируйте все элементы для контекстного меню, 417передав {@link android.widget.ListView} или {@link android.widget.GridView} методу {@link 418android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.</p> 419</li> 420 421 <li>Реализуйте метод {@link 422android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} в 423 {@link android.app.Activity} или {@link android.app.Fragment}. 424 <p>Когда зарегистрированное представление примет событие длительного нажатия, система вызовет ваш метод {@link 425android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} 426. Именно здесь определяются пункты меню. Делается это обычно путем загрузки ресурса меню. Например: 427</p> 428<pre> 429@Override 430public void onCreateContextMenu(ContextMenu menu, View v, 431 ContextMenuInfo menuInfo) { 432 super.onCreateContextMenu(menu, v, menuInfo); 433 MenuInflater inflater = getMenuInflater(); 434 inflater.inflate(R.menu.context_menu, menu); 435} 436</pre> 437 438<p>{@link android.view.MenuInflater} позволяет загружать контекстное меню из <a href="{@docRoot}guide/topics/resources/menu-resource.html">ресурса меню</a>. В число параметров метода 439обратного вызова входят {@link android.view.View}, 440выбранный пользователем, и объект{@link android.view.ContextMenu.ContextMenuInfo}, который предоставляет 441дополнительную информацию о выбранном элементе. Если в вашей операции есть несколько представлений и все они предоставляют 442разные контекстные меню, то с помощью этих параметров можно определять, какое контекстное меню 443загружать.</p> 444</li> 445 446<li>Реализуйте метод {@link android.app.Activity#onContextItemSelected(MenuItem) 447onContextItemSelected()}. 448 <p>Когда пользователь выбирает пункт меню, система вызывает этот метод, с тем чтобы вы могли выполнить 449соответствующее действие. Например:</p> 450 451<pre> 452@Override 453public boolean onContextItemSelected(MenuItem item) { 454 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 455 switch (item.getItemId()) { 456 case R.id.edit: 457 editNote(info.id); 458 return true; 459 case R.id.delete: 460 deleteNote(info.id); 461 return true; 462 default: 463 return super.onContextItemSelected(item); 464 } 465} 466</pre> 467 468<p>Метод {@link android.view.MenuItem#getItemId()} запрашивает идентификатор для 469выбранного пункта меню. Идентификаторы должны быть назначены каждому пункту меню в файле XML с помощью атрибута {@code 470android:id}, как описано в разделе <a href="#xml">Определение меню в файле 471XML</a>.</p> 472 473<p>Когда пункт меню успешно обработан, возвращается {@code true}. Если пункт меню не 474обрабатывается, следует передать его реализации суперкласса. Если в вашей операции есть фрагменты, 475то она получит этот обратный вызов первой. Вызывая суперкласс, когда пункт меню не обрабатывается, система 476передает событие соответствующему методу обратного вызова в каждом фрагменте по одному (в порядке 477добавления каждого фрагмента), пока не будет возвращено значение {@code true} или {@code false}. (Реализация 478{@link android.app.Activity} и {@code android.app.Fragment} по умолчанию возвращает {@code 479false}, поэтому, когда событие не обрабатывается, следует всегда вызывать суперкласс.)</p> 480</li> 481</ol> 482 483 484<h3 id="CAB">Использование режима контекстных действий</h3> 485 486<p>Режим контекстных действий представляет собой системную реализацию класса {@link android.view.ActionMode}, которая 487направляет пользователя на выполнение контекстных действий при взаимодействии с приложением. Когда 488пользователь использует этот режим, выбирая элемент, вверху экрана открывается <em>строка контекстных действий</em>, 489содержащая действия, которые пользователь может выполнить с выбранными в данный момент элементами. В этом режиме 490пользователь может выбирать несколько элементов (если это допускается приложением), снимать выделения с элементов и продолжать 491навигацию в операции (в тех пределах, в которых это поддерживается приложением). Режим контекстных действий отключается, 492а строка контекстных действий исчезает, когда пользователь снимет выделение со всех элементов, нажмет кнопку НАЗАД 493или выберет действие <em>Готово</em>, расположенное с левой стороны строки.</p> 494 495<p class="note"><strong>Примечание.</strong> Строка контекстных действий не обязательно бывает 496связана со <a href="{@docRoot}guide/topics/ui/actionbar.html">строкой действий</a>. Они работают 497независимо друг от друга, даже несмотря на то, что визуально строка контекстных действий занимает положение 498строки действий.</p> 499 500<p>Если вы разрабатываете приложение для версии Android 3.0 (уровень API 11) или последующих версий, то 501обычно вместо <a href="#FloatingContextMenu">плавающего контекстного меню</a> вам следует использовать контекстные действия.</p> 502 503<p>Для представлений, которые предоставляют возможность контекстные действия, обычно следует вызывать режим контекстных действий 504при возникновении одного из двух (или сразу обоих) событий:</p> 505<ul> 506 <li>пользователь длительно нажимает в представлении;</li> 507 <li>пользователь устанавливает флажок или выбирает другой подобный компонент пользовательского интерфейса в представлении.</li> 508</ul> 509 510<p>То, каким образом ваше представление вызывает режим контекстных действий и определяет поведение каждого 511действия, зависит от вас. Есть два базовых варианта:</p> 512<ul> 513 <li>для контекстных действий в отдельных, произвольных представлениях;</li> 514 <li>для пакетных контекстных действий с группами элементов в {@link 515android.widget.ListView} или {@link android.widget.GridView} (что позволяет пользователю выбирать по несколько 516элементов и выполнять действие с ними всеми).</li> 517</ul> 518 519<p>В следующих разделах описывается конфигурация, необходимая для каждого из этих вариантов.</p> 520 521 522<h4 id="CABforViews">Включение режима контекстных действий для отдельных представлений</h4> 523 524<p>Если вам требуется вызывать режим контекстных действий, только когда пользователь выбирает определенные 525представления, то вам следует:</p> 526<ol> 527 <li>Реализовать интерфейс {@link android.view.ActionMode.Callback}. В его методах обратного вызова вы 528можете указать действия для строки контекстных действий, реагировать на нажатия пунктов действий и 529обрабатывать другие события жизненного цикла для режима действий.</li> 530 <li>Вызывайте {@link android.app.Activity#startActionMode startActionMode()}, когда требуется показать 531строку (например, когда пользователь выполняет длительное нажатие представления).</li> 532</ol> 533 534<p>Например:</p> 535 536<ol> 537 <li>Реализуйте интерфейс {@link android.view.ActionMode.Callback ActionMode.Callback}: 538<pre> 539private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { 540 541 // Called when the action mode is created; startActionMode() was called 542 @Override 543 public boolean onCreateActionMode(ActionMode mode, Menu menu) { 544 // Inflate a menu resource providing context menu items 545 MenuInflater inflater = mode.getMenuInflater(); 546 inflater.inflate(R.menu.context_menu, menu); 547 return true; 548 } 549 550 // Called each time the action mode is shown. Always called after onCreateActionMode, but 551 // may be called multiple times if the mode is invalidated. 552 @Override 553 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 554 return false; // Return false if nothing is done 555 } 556 557 // Called when the user selects a contextual menu item 558 @Override 559 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 560 switch (item.getItemId()) { 561 case R.id.menu_share: 562 shareCurrentItem(); 563 mode.finish(); // Action picked, so close the CAB 564 return true; 565 default: 566 return false; 567 } 568 } 569 570 // Called when the user exits the action mode 571 @Override 572 public void onDestroyActionMode(ActionMode mode) { 573 mActionMode = null; 574 } 575}; 576</pre> 577 578<p>Обратите внимание, что эти обратные вызовы событий почти точно такие же, как и обратные вызовы для <a href="#options-menu">меню параметров</a>. Отличаются они только тем, что каждый из них также передает объект {@link 579android.view.ActionMode}, связанный с событием. С помощью API-интерфейсов {@link 580android.view.ActionMode} можно вносить различные изменения в CAB, например, указывать другой заголовок и 581подзаголовок с помощью {@link android.view.ActionMode#setTitle setTitle()} и {@link 582android.view.ActionMode#setSubtitle setSubtitle()} (удобно для указания количества выбранных 583элементов).</p> 584 585<p>Также обратите внимание, что приведенный выше образец кода задает для переменной {@code mActionMode} значение null, когда 586режим действия прекращает свое существование. Далее вы узнаете, каким образом он инициализируется и чем может быть 587полезно сохранение составной переменной в операции или фрагменте.</p> 588</li> 589 590 <li>Для включения режима контекстных действий, когда это необходимо, 591например, в ответ на длительное нажатие {@link 592android.view.View}, вызывайте {@link android.app.Activity#startActionMode startActionMode()}:</p> 593 594<pre> 595someView.setOnLongClickListener(new View.OnLongClickListener() { 596 // Called when the user long-clicks on someView 597 public boolean onLongClick(View view) { 598 if (mActionMode != null) { 599 return false; 600 } 601 602 // Start the CAB using the ActionMode.Callback defined above 603 mActionMode = getActivity().startActionMode(mActionModeCallback); 604 view.setSelected(true); 605 return true; 606 } 607}); 608</pre> 609 610<p>При вызове метода {@link android.app.Activity#startActionMode startActionMode()} система возвращает 611созданный класс {@link android.view.ActionMode}. Сохранив его в составной переменной, вы сможете 612вносить изменения в строку контекстных действий в ответ на другие события. В приведенном выше образце кода 613{@link android.view.ActionMode} используется для того, чтобы экземпляр {@link android.view.ActionMode} 614не создавался повторно, если он уже активен. Достигается это путем проверки, имеет ли элемент значение null перед запуском 615режима действий.</p> 616</li> 617</ol> 618 619 620 621<h4 id="CABforListView">Включение пакетных контекстных действий в ListView или GridView</h4> 622 623<p>Если при наличии набора элементов в {@link android.widget.ListView} или {@link 624android.widget.GridView} (либо другом расширении {@link android.widget.AbsListView}) требуется 625разрешить пользователям выполнять пакетные действия, следует:</p> 626 627<ul> 628 <li>реализовать интерфейс {@link android.widget.AbsListView.MultiChoiceModeListener} и задать его 629для группы представлений с помощью метода {@link android.widget.AbsListView#setMultiChoiceModeListener 630setMultiChoiceModeListener()}; в методах обратного вызова приемника событий вы можете указывать действия 631для строки контекстных действий, реагировать на нажатия пунктов действий и обрабатывать другие обратные вызовы, 632унаследованные от интерфейса {@link android.view.ActionMode.Callback};</li> 633 634 <li>вызвать метод {@link android.widget.AbsListView#setChoiceMode setChoiceMode()} с аргументом {@link 635android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.</li> 636</ul> 637 638<p>Например:</p> 639 640<pre> 641ListView listView = getListView(); 642listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 643listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { 644 645 @Override 646 public void onItemCheckedStateChanged(ActionMode mode, int position, 647 long id, boolean checked) { 648 // Here you can do something when items are selected/de-selected, 649 // such as update the title in the CAB 650 } 651 652 @Override 653 public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 654 // Respond to clicks on the actions in the CAB 655 switch (item.getItemId()) { 656 case R.id.menu_delete: 657 deleteSelectedItems(); 658 mode.finish(); // Action picked, so close the CAB 659 return true; 660 default: 661 return false; 662 } 663 } 664 665 @Override 666 public boolean onCreateActionMode(ActionMode mode, Menu menu) { 667 // Inflate the menu for the CAB 668 MenuInflater inflater = mode.getMenuInflater(); 669 inflater.inflate(R.menu.context, menu); 670 return true; 671 } 672 673 @Override 674 public void onDestroyActionMode(ActionMode mode) { 675 // Here you can make any necessary updates to the activity when 676 // the CAB is removed. By default, selected items are deselected/unchecked. 677 } 678 679 @Override 680 public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 681 // Here you can perform updates to the CAB due to 682 // an {@link android.view.ActionMode#invalidate} request 683 return false; 684 } 685}); 686</pre> 687 688<p>Готово. Теперь, когда пользователь выберет элемент с помощью длительного нажатия, система вызовет метод {@link 689android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()} 690и отобразит строку контекстных действий с указанными действиями. Пока строка 691контекстных действий отображается, пользователи могут выбирать дополнительные элементы.</p> 692 693<p>В некоторых случаях, когда контекстные действия содержат общие пункты, можно 694добавить флажок или другой подобный элемент пользовательского интерфейса, с помощью которого пользователи могут выбирать пункты, поскольку они 695могут не обнаружить варианта с длительным нажатием. Когда пользователь устанавливает флажок, можно 696вызывать режим контекстных действий, переводя соответствующий элемент списка в выбранное 697состояние с помощью {@link android.widget.AbsListView#setItemChecked setItemChecked()}.</p> 698 699 700 701 702<h2 id="PopupMenu">Создание всплывающего меню</h2> 703 704<div class="figure" style="width:220px"> 705<img src="{@docRoot}images/ui/popupmenu.png" alt="" /> 706<p><strong>Рисунок 4</strong>. Всплывающее меню в приложении Gmail, привязанное к расположенной вверху справа кнопке открытия панели 707дополнительных пунктов.</p> 708</div> 709 710<p>{@link android.widget.PopupMenu} является модальным меню, привязанным к {@link android.view.View}. 711Оно отображается ниже представления, к которому привязано, если там есть место, либо поверх него. Варианты использования:</p> 712<ul> 713 <li>Предоставление меню с дополнительными пунктами для действий, которые <em>относятся к</em> определенному контенту (например, 714к заголовкам сообщений Gmail, показанным на рисунке 4). 715 <p class="note"><strong>Примечание.</strong> Оно отличается от контекстного меню, которое 716обычно используется для действий, <em>затрагивающих</em> выбранный контент. Для действий, которые затрагивают выбранный 717контент, используйте <a href="#CAB">режим контекстных действий</a> или <a href="#FloatingContextMenu">плавающее контекстное меню</a>.</p></li> 718 <li>Предоставление второй части командной последовательности (например, кнопки, обозначенной как "Добавить", 719которая открывает всплывающее меню с различными вариантами добавления);</li> 720 <li>Предоставление раскрывающегося меню наподобие {@link android.widget.Spinner}, которое не сохраняет 721постоянное выделение.</li> 722</ul> 723 724 725<p class="note"><strong>Примечание.</strong> Использование класса {@link android.widget.PopupMenu} поддерживается на уровне API 726 11 и выше.</p> 727 728<p>Если для <a href="#xml">определения меню используется XML</a>, вот каким образом можно показать всплывающее меню:</p> 729<ol> 730 <li>Создайте экземпляр класса {@link android.widget.PopupMenu} с помощью его конструктора, принимающий 731текущие {@link android.content.Context} и {@link android.view.View} приложения, к которым 732должно быть привязано меню.</li> 733 <li>С помощью {@link android.view.MenuInflater} загрузите свой ресурс меню в объект {@link 734android.view.Menu}, возвращенный методом {@link 735android.widget.PopupMenu#getMenu() PopupMenu.getMenu()}. На API уровня 14 и выше вместо этого можно использовать 736{@link android.widget.PopupMenu#inflate PopupMenu.inflate()}.</li> 737 <li>Вызовите метод {@link android.widget.PopupMenu#show() PopupMenu.show()}.</li> 738</ol> 739 740<p>Например, вот кнопка с атрибутом {@link android.R.attr#onClick android:onClick}, 741которая показывает всплывающее меню:</p> 742 743<pre> 744<ImageButton 745 android:layout_width="wrap_content" 746 android:layout_height="wrap_content" 747 android:src="@drawable/ic_overflow_holo_dark" 748 android:contentDescription="@string/descr_overflow_button" 749 android:onClick="showPopup" /> 750</pre> 751 752<p>После этого операция сможет показать вот такое всплывающее меню:</p> 753 754<pre> 755public void showPopup(View v) { 756 PopupMenu popup = new PopupMenu(this, v); 757 MenuInflater inflater = popup.getMenuInflater(); 758 inflater.inflate(R.menu.actions, popup.getMenu()); 759 popup.show(); 760} 761</pre> 762 763<p>На API уровня 14 и выше можно объединить две строки, которые загружают меню, с помощью {@link 764android.widget.PopupMenu#inflate PopupMenu.inflate()}.</p> 765 766<p>Меню закрывается, когда пользователь выбирает один из пунктов или касается экрана за пределами области 767меню. Прослушивать событие закрытия меню можно с помощью {@link 768android.widget.PopupMenu.OnDismissListener}.</p> 769 770<h3 id="PopupEvents">Обработка нажатий</h3> 771 772<p>Для выполнения 773действия, когда пользователь выбирает пункт меню, необходимо реализовать интерфейс {@link 774android.widget.PopupMenu.OnMenuItemClickListener} и зарегистрировать его в своем {@link 775android.widget.PopupMenu}, вызвав метод {@link android.widget.PopupMenu#setOnMenuItemClickListener 776setOnMenuItemclickListener()}. Когда пользователь выбирает пункт меню, система выполняет обратный вызов {@link 777android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} в 778вашем интерфейсе.</p> 779 780<p>Например:</p> 781 782<pre> 783public void showMenu(View v) { 784 PopupMenu popup = new PopupMenu(this, v); 785 786 // This activity implements OnMenuItemClickListener 787 popup.setOnMenuItemClickListener(this); 788 popup.inflate(R.menu.actions); 789 popup.show(); 790} 791 792@Override 793public boolean onMenuItemClick(MenuItem item) { 794 switch (item.getItemId()) { 795 case R.id.archive: 796 archive(item); 797 return true; 798 case R.id.delete: 799 delete(item); 800 return true; 801 default: 802 return false; 803 } 804} 805</pre> 806 807 808<h2 id="groups">Создание групп меню</h2> 809 810<p>Группа меню ― это набор пунктов меню с рядом общих характеристик. С помощью группы 811можно:</p> 812<ul> 813 <li>показывать или скрывать все пункты с помощью {@link android.view.Menu#setGroupVisible(int,boolean) 814setGroupVisible()};</li> 815 <li>включать или отключать все пункты с помощью {@link android.view.Menu#setGroupEnabled(int,boolean) 816setGroupEnabled()};</li> 817 <li>Указывать, можно ли помечать все пункты, с помощью {@link 818android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}.</li> 819</ul> 820 821<p>Для создания группы необходимо вложить элементы {@code <item>} в элемент {@code <group>} 822в своем ресурсе меню либо указать идентификатор группы с помощью метода {@link 823android.view.Menu#add(int,int,int,int) add()}.</p> 824 825<p>Вот пример ресурса меню, в котором имеется группа:</p> 826 827<pre> 828<?xml version="1.0" encoding="utf-8"?> 829<menu xmlns:android="http://schemas.android.com/apk/res/android"> 830 <item android:id="@+id/menu_save" 831 android:icon="@drawable/menu_save" 832 android:title="@string/menu_save" /> 833 <!-- menu group --> 834 <group android:id="@+id/group_delete"> 835 <item android:id="@+id/menu_archive" 836 android:title="@string/menu_archive" /> 837 <item android:id="@+id/menu_delete" 838 android:title="@string/menu_delete" /> 839 </group> 840</menu> 841</pre> 842 843<p>Элементы, находящиеся в группе, отображаются на одном уровне с первым элементом — все три пункта 844меню являются элементами одного уровня. Однако можно изменить характеристики двух 845пунктов из группы, указав ссылку на идентификатор группы и воспользовавшись приведенными выше методами. Кроме того, 846система никогда не будет разделять сгруппированные пункты. Например, если объявить {@code 847android:showAsAction="ifRoom"} для каждого пункта, то они оба будут отображены либо в строке 848действий, либо в дополнительных действиях.</p> 849 850 851<h3 id="checkable">Использование пунктов меню, которые можно пометить</h3> 852 853<div class="figure" style="width:200px"> 854 <img src="{@docRoot}images/radio_buttons.png" height="333" alt="" /> 855 <p class="img-caption"><strong>Рисунок 5</strong>. Снимок экрана с вложенным меню, пункты которого можно 856пометить.</p> 857</div> 858 859<p>Такое меню можно использовать в качестве интерфейса для включения и отключения тех или иных параметров. При этом для автономных 860параметров используется флажок, а для групп 861взаимоисключающих вариантов ― переключатель. На рисунке 5 показано вложенное меню с пунктами, которые можно выбирать с помощью 862переключателей.</p> 863 864<p class="note"><strong>Примечание.</strong> Пункты в меню значков (из меню параметров) не могут 865отображать флажки или переключатели. Если вы решите сделать так, чтобы пункты меню значков можно было помечать, 866вам необходимо будет вручную указать помеченное состояние путем замены значка и/или теста 867при каждом изменении состояния.</p> 868 869<p>Определять возможность помечать отдельные пункты меню можно с помощью атрибута {@code 870android:checkable} в элементе {@code <item>}, а для всей группы это делается с помощью 871атрибута {@code android:checkableBehavior} в элементе {@code <group>}. Например 872, все пункты этой группы меню можно помечать с помощью переключателей:</p> 873 874<pre> 875<?xml version="1.0" encoding="utf-8"?> 876<menu xmlns:android="http://schemas.android.com/apk/res/android"> 877 <group android:checkableBehavior="single"> 878 <item android:id="@+id/red" 879 android:title="@string/red" /> 880 <item android:id="@+id/blue" 881 android:title="@string/blue" /> 882 </group> 883</menu> 884</pre> 885 886<p>Атрибут {@code android:checkableBehavior} принимает один из трех параметров: 887<dl> 888 <dt>{@code single}</dt> 889 <dd>Только один пункт из группы можно пометить (переключатель)</dd> 890 <dt>{@code all}</dt> 891 <dd>Все пункты можно пометить (флажки)</dd> 892 <dt>{@code none}</dt> 893 <dd>Пометить нельзя ни один пункт</dd> 894</dl> 895 896<p>Для того чтобы применить к пункту помеченное состояние по умолчанию, служит атрибут {@code android:checked} в 897элементе {@code <item>}, а изменить его в коде можно с помощью метода {@link 898android.view.MenuItem#setChecked(boolean) setChecked()}.</p> 899 900<p>Когда выбирается пункт, который может быть помечен, система вызывает соответствующий ему метод обратного вызова 901(например {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). Именно 902здесь необходимо задать состояние флажка, поскольку флажок или переключатель не 903изменяет свое состояние автоматически. Запросить текущее состояние пункта (в котором он находился до того, как был 904выбран пользователем) можно с помощью{@link android.view.MenuItem#isChecked()}, а затем задать помеченное состояние с помощью 905{@link android.view.MenuItem#setChecked(boolean) setChecked()}. Например:</p> 906 907<pre> 908@Override 909public boolean onOptionsItemSelected(MenuItem item) { 910 switch (item.getItemId()) { 911 case R.id.vibrate: 912 case R.id.dont_vibrate: 913 if (item.isChecked()) item.setChecked(false); 914 else item.setChecked(true); 915 return true; 916 default: 917 return super.onOptionsItemSelected(item); 918 } 919} 920</pre> 921 922<p>Если помеченное состояние не установить этим способом, то, когда пользователь выберет пункт, его отображаемое состояние (флажок или 923переключатель) не 924изменится. Если же помеченное состояние установить, операция сохранит его 925для пункта, с тем чтобы, когда пользователь откроет это меню, он увидел, 926что галочка поставлена.</p> 927 928<p class="note"><strong>Примечание.</strong> 929Пункты меню, которые можно пометить галочкой, предназначены для использования только в рамках одного сеанса. Они не сохраняются после 930прекращения существования приложения. Если имеются настройки приложения, которые требуется сохранить для пользователя, 931делать это следует с помощью <a href="{@docRoot}guide/topics/data/data-storage.html#pref">общих настроек</a>.</p> 932 933 934 935<h2 id="intents">Добавление пунктов меню на основе объектов Intent</h2> 936 937<p>Иногда требуется, чтобы пункт меню запускал операцию с помощью объекта {@link android.content.Intent} 938(это может быть операция как из вашего, так и из другого приложения). Когда вам известен объект Intent, который 939требуется использовать, и у вас есть определенный пункт меню, который должен инициировать этот объект Intent, можно выполнить объект 940Intent с помощью {@link android.app.Activity#startActivity(Intent) startActivity()} во время 941выполнения соответствующего метода обратного вызова, запускаемого при выборе пункта меню (например, обратного вызова {@link 942android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}).</p> 943 944<p>Однако если вы не уверены, что на устройстве пользователя 945есть приложение, которое может обработать этот объект Intent, добавление пункта меню, который его вызывает, может привести 946к тому, что он не будет работать, поскольку объект Intent может не быть передан в 947операцию. Чтобы решить эту проблему, Android позволяет динамически добавлять в меню пункты, 948когда система Android обнаруживает на устройстве операции, которые могут обработать ваш объект Intent.</p> 949 950<p>Добавление пунктов меню на основе имеющихся операций, которые принимают объект Intent:</p> 951<ol> 952 <li>Определите объект 953с категорией {@link android.content.Intent#CATEGORY_ALTERNATIVE} и/или 954{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, а также с любыми другими условиями.</li> 955 <li>Вызовите метод {@link 956android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) 957Menu.addIntentOptions()}. Затем Android выполнит поиск приложений, которые могут выполнить этот объект Intent, 958и добавит их в ваше меню.</li> 959</ol> 960 961<p>При отсутствии установленных приложений, 962которые удовлетворяют требованиям объекта Intent, ни одного пункта меню добавлено не будет.</p> 963 964<p class="note"><strong>Примечание.</strong> 965{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} используется для обработки элемента, выбранного 966в данный момент на экране. Поэтому его следует использовать только при создании меню в {@link 967android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) 968onCreateContextMenu()}.</p> 969 970<p>Например:</p> 971 972<pre> 973@Override 974public boolean onCreateOptionsMenu(Menu menu){ 975 super.onCreateOptionsMenu(menu); 976 977 // Create an Intent that describes the requirements to fulfill, to be included 978 // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE. 979 Intent intent = new Intent(null, dataUri); 980 intent.addCategory(Intent.CATEGORY_ALTERNATIVE); 981 982 // Search and populate the menu with acceptable offering applications. 983 menu.addIntentOptions( 984 R.id.intent_group, // Menu group to which new items will be added 985 0, // Unique item ID (none) 986 0, // Order for the items (none) 987 this.getComponentName(), // The current activity name 988 null, // Specific items to place first (none) 989 intent, // Intent created above that describes our requirements 990 0, // Additional flags to control items (none) 991 null); // Array of MenuItems that correlate to specific items (none) 992 993 return true; 994}</pre> 995 996<p>Каждая обнаруженная операция, в которой имеется фильтр Intent, соответствующий данному объекту Intent, добавляется в виде 997пункта меню. Для этого значение из элемента <code>android:label</code> фильтра Intent используется в качестве 998заголовка пункта меню, а значок приложения ― в качестве значка этого пункта меню. Метод 999{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) 1000addIntentOptions()} возвращает количество добавленных пунктов меню.</p> 1001 1002<p class="note"><strong>Примечание.</strong> При вызове метода {@link 1003android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) 1004addIntentOptions()} он переопределяет все пункты меню по группе меню, указанной в первом 1005аргументе.</p> 1006 1007 1008<h3 id="AllowingToAdd">Предоставление возможности добавить свою операцию в другие меню</h3> 1009 1010<p>Вы также можете предоставить другим приложениям возможность воспользоваться своей операцией, с тем чтобы ваше 1011приложение могло быть включено в меню других приложений (процедура, обратная описанной выше).</p> 1012 1013<p>Чтобы операция могла быть включена в меню других приложений, необходимо определить фильтр 1014Intent обычным образом, но непременно включить в него значения {@link android.content.Intent#CATEGORY_ALTERNATIVE} 1015и/или {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} для категории фильтра 1016Intent. Например:</p> 1017<pre> 1018<intent-filter label="@string/resize_image"> 1019 ... 1020 <category android:name="android.intent.category.ALTERNATIVE" /> 1021 <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> 1022 ... 1023</intent-filter> 1024</pre> 1025 1026<p>Подробные сведения о написании фильтров Intent см. в документе 1027<a href="/guide/components/intents-filters.html">Объекты Intent и фильтры объектов Intent</a>.</p> 1028 1029<p>Образец приложения, в котором используется эта методика, см. в образце кода 1030<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note 1031Pad</a>.</p> 1032