• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> должны напрямую затрагивать соответствующий контент &mdash; для этого предназначены контекстные
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>&lt;menu></code></dt>
131    <dd>Определяет класс {@link android.view.Menu}, который является контейнером для пунктов меню. Элемент
132<code>&lt;menu></code> должен быть корневым узлом файла, в котором может находиться один или несколько элементов
133<code>&lt;item></code> и <code>&lt;group></code>.</dd>
134
135  <dt><code>&lt;item></code></dt>
136    <dd>Создает класс {@link android.view.MenuItem}, который представляет один пункт меню. Этот
137элемент может содержать вложенный элемент <code>&lt;menu></code> для создания вложенных меню.</dd>
138
139  <dt><code>&lt;group></code></dt>
140    <dd>Необязательный, невидимый контейнер для элементов {@code &lt;item&gt;}. Он позволяет
141разделять пункты меню на категории и назначать им одинаковые свойства, такие как активное состояние и видимость. Подробные
142сведения изложены в разделе <a href="#groups">Создание групп меню</a>.</dd>
143</dl>
144
145
146<p>Вот пример меню с именем <code>game_menu.xml</code>:</p>
147<pre>
148&lt;?xml version="1.0" encoding="utf-8"?&gt;
149&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
150    &lt;item android:id="@+id/new_game"
151          android:icon="@drawable/ic_new_game"
152          android:title="@string/new_game"
153          android:showAsAction="ifRoom"/&gt;
154    &lt;item android:id="@+id/help"
155          android:icon="@drawable/ic_help"
156          android:title="@string/help" /&gt;
157&lt;/menu&gt;
158</pre>
159
160<p>Элемент <code>&lt;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 &lt;menu&gt;}
179в качестве дочернего элемента {@code &lt;item&gt;}. Вложенные меню полезны, когда в приложении имеется множество
180функций, которые можно разделить на категории подобно строке меню приложения для ПК ("Файл",
181"Правка", "Вид" и т. д.). Например:</p>
182
183<pre>
184&lt;?xml version="1.0" encoding="utf-8"?&gt;
185&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
186    &lt;item android:id="@+id/file"
187          android:title="@string/file" &gt;
188        &lt;!-- "file" submenu --&gt;
189        &lt;menu&gt;
190            &lt;item android:id="@+id/create_new"
191                  android:title="@string/create_new" /&gt;
192            &lt;item android:id="@+id/open"
193                  android:title="@string/open" /&gt;
194        &lt;/menu&gt;
195    &lt;/item&gt;
196&lt;/menu&gt;
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 &lt;item&gt;} (см. рисунок
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 &lt;item&gt;}, который требуется переместить.</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&#64;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&#64;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}, &mdash; когда система
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&#64;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&#64;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    &#64;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    &#64;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    &#64;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    &#64;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    &#64;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    &#64;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    &#64;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    &#64;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    &#64;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&lt;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&#64;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 &lt;item&gt;} в элемент {@code &lt;group&gt;}
822в своем ресурсе меню либо указать идентификатор группы с помощью метода {@link
823android.view.Menu#add(int,int,int,int) add()}.</p>
824
825<p>Вот пример ресурса меню, в котором имеется группа:</p>
826
827<pre>
828&lt;?xml version="1.0" encoding="utf-8"?&gt;
829&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
830    &lt;item android:id="@+id/menu_save"
831          android:icon="@drawable/menu_save"
832          android:title="@string/menu_save" /&gt;
833    &lt;!-- menu group --&gt;
834    &lt;group android:id="@+id/group_delete"&gt;
835        &lt;item android:id="@+id/menu_archive"
836              android:title="@string/menu_archive" /&gt;
837        &lt;item android:id="@+id/menu_delete"
838              android:title="@string/menu_delete" /&gt;
839    &lt;/group&gt;
840&lt;/menu&gt;
841</pre>
842
843<p>Элементы, находящиеся в группе, отображаются на одном уровне с первым элементом &mdash; все три пункта
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 &lt;item&gt;}, а для всей группы это делается с помощью
871атрибута {@code android:checkableBehavior} в элементе {@code &lt;group&gt;}. Например
872, все пункты этой группы меню можно помечать с помощью переключателей:</p>
873
874<pre>
875&lt;?xml version="1.0" encoding="utf-8"?&gt;
876&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
877    &lt;group android:checkableBehavior="single"&gt;
878        &lt;item android:id="@+id/red"
879              android:title="@string/red" /&gt;
880        &lt;item android:id="@+id/blue"
881              android:title="@string/blue" /&gt;
882    &lt;/group&gt;
883&lt;/menu&gt;
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 &lt;item&gt;}, а изменить его в коде можно с помощью метода {@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&#64;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&#64;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&lt;intent-filter label="&#64;string/resize_image">
1019    ...
1020    &lt;category android:name="android.intent.category.ALTERNATIVE" />
1021    &lt;category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
1022    ...
1023&lt;/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