| page.title=События ввода |
| parent.title=Пользовательский интерфейс |
| parent.link=index.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Содержание документа</h2> |
| <ol> |
| <li><a href="#EventListeners">Приемники событий</a></li> |
| <li><a href="#EventHandlers">Обработчики событий</a></li> |
| <li><a href="#TouchMode">Режим касания</a></li> |
| <li><a href="#HandlingFocus">Фокус обработки</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| <p>В системе Android предусмотрено несколько способов перехвата событий взаимодействия пользователя с вашим приложением. |
| Что касается событий в пользовательском интерфейсе, подход состоит в том, чтобы захватывать события из |
| определенного представления объекта, с которым взаимодействует пользователь. Класс отображаемых объектов (View) содержит средства, позволяющие делать это.</p> |
| |
| <p>В различных классах View, которые вы будете использовать для создания макета, вы заметите несколько общедоступных методов обратного вызова, |
| полезных для работы с событиями пользовательского интерфейса. Эти методы вызываются платформой Android, когда |
| с этим объектом выполняется соответствующее действие. Например, когда пользователь касается отображаемого объекта (кнопки), |
| вызывается метод <code>onTouchEvent()</code> этого объекта. Однако для перехвата этого события вы должны |
| наследовать класс и переопределить метод. Однако наследование каждого отображаемого объекта |
| для обработки такого события было бы неудобно. Именно поэтому класс View также содержит |
| набор вложенных интерфейсов с обратными вызовами, которые можно задать значительно проще. Эти интерфейсы, |
| которые называются <a href="#EventListeners">приемниками событий</a>, и служат перехватчиками действий пользователя с вашим пользовательским интерфейсом.</p> |
| |
| <p>Несмотря на то, что вы будете чаще использовать приемники событий для перехвата действий пользователя, может |
| наступить момент, когда вам не захочется наследовать класс View, чтобы создать нестандартный компонент. |
| Возможно, вы захотите наследовать класс {@link android.widget.Button}, |
| чтобы сделать нечто более необычное. В этом случае вы сможете определить поведение события по умолчанию для своего |
| класса с помощью <a href="#EventHandlers">обработчиков событий</a> класса.</p> |
| |
| |
| <h2 id="EventListeners">Приемники событий</h2> |
| |
| <p>Приемник событий — это интерфейс в классе {@link android.view.View}, который содержит один |
| метод обратного вызова. Эти методы будут вызываться платформой Android, когда в результате взаимодействия пользователя с объектом |
| пользовательского интерфейса срабатывает отображаемый объект View, в котором зарегистрирован приемник.</p> |
| |
| <p>Интерфейсы, включенные в приемник события, представляют собой следующие методы обратного вызова:</p> |
| |
| <dl> |
| <dt><code>onClick()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnClickListener}. |
| Этот метод вызывается, когда пользователь касается элемента |
| (в режиме касания), или переводит фокус на элемент с помощью клавиш перемещения или трекбола и |
| нажимает соответствующую клавишу «ввода» или нажимает на трекбол.</dd> |
| <dt><code>onLongClick()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnLongClickListener}. |
| Этот метод вызывается, когда пользователь касается элемента и удерживает его (в режиме касания), |
| или переводит фокус на элемент с помощью клавиш перемещения или трекбола и |
| нажимает и удерживает соответствующую клавишу «ввода» или трекбол (в течение одной секунды).</dd> |
| <dt><code>onFocusChange()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnFocusChangeListener}. |
| Этот метод вызывается, когда пользователь перемещается в элемент или из него с помощью клавиш перемещения или трекбола.</dd> |
| <dt><code>onKey()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnKeyListener}. |
| Этот метод вызывается, когда пользователь переносит фокус на элемент и нажимает или отпускает аппаратную клавишу на устройстве.</dd> |
| <dt><code>onTouch()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnTouchListener}. |
| Этот метод вызывается, когда пользователь выполняет действие, считающееся событием касания, например, нажимает, отпускает |
| или выполняет любой жест на экране (в пределах границ элемента).</dd> |
| <dt><code>onCreateContextMenu()</code></dt> |
| <dd>Из объекта {@link android.view.View.OnCreateContextMenuListener}. |
| Этот метод вызывается, когда создается контекстное меню (в результате длительного «длительного нажатия»). См. обсуждение |
| контекстных меню в руководстве |
| для разработчиков <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Меню</a>.</dd> |
| </dl> |
| |
| <p>Эти методы являются единственными составными частями соответствующих интерфейсов. Чтобы определить один из этих методов |
| и обрабатывать события, реализуйте вложенный интерфейс в вашем процесс или определите его, как анонимный класс. |
| Затем передайте экземпляр реализации |
| в соответствующий метод <code>View.set...Listener()</code>. (Например, вызовите |
| <code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code> |
| и передайте ему свою реализацию {@link android.view.View.OnClickListener OnClickListener}.)</p> |
| |
| <p>В следующем примере показано, как зарегистрировать приемник события «по клику» (on-click) для кнопки. </p> |
| |
| <pre> |
| // Create an anonymous implementation of OnClickListener |
| private OnClickListener mCorkyListener = new OnClickListener() { |
| public void onClick(View v) { |
| // do something when the button is clicked |
| } |
| }; |
| |
| protected void onCreate(Bundle savedValues) { |
| ... |
| // Capture our button from layout |
| Button button = (Button)findViewById(R.id.corky); |
| // Register the onClick listener with the implementation above |
| button.setOnClickListener(mCorkyListener); |
| ... |
| } |
| </pre> |
| |
| <p>Возможно, еще удобнее реализовать OnClickListener как часть вашей операции. |
| При этом исключается дополнительная нагрузка класса и выделение объекта. Например:</p> |
| <pre> |
| public class ExampleActivity extends Activity implements OnClickListener { |
| protected void onCreate(Bundle savedValues) { |
| ... |
| Button button = (Button)findViewById(R.id.corky); |
| button.setOnClickListener(this); |
| } |
| |
| // Implement the OnClickListener callback |
| public void onClick(View v) { |
| // do something when the button is clicked |
| } |
| ... |
| } |
| </pre> |
| |
| <p>Обратите внимание, что обратный вызов <code>onClick()</code> в примере выше не |
| содержит возвращаемого значения, но некоторые другие методы приемника события должны возвращать логическое значение. Причина |
| зависит от события. Для некоторых методов, которые возвращают значения, причина описана ниже:</p> |
| <ul> |
| <li><code>{@link android.view.View.OnLongClickListener#onLongClick(View) onLongClick()}</code> — |
| этот метод возвращает логическое значение, указывающее, что вы обработали это событие и его более не следует хранить. |
| А именно, верните значение <em>true</em>, чтобы указать, что вы обработали событие и его следует остановить; |
| верните значение <em>false</em>, если вы не обработали его и/или событие должно продолжаться для любых других |
| приемников события on-click.</li> |
| <li><code>{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent) onKey()}</code> — |
| этот метод возвращает логическое значение, указывающее, что вы обработали это событие и его более не следует хранить. |
| А именно, верните значение <em>true</em>, чтобы указать, что вы обработали событие и его следует остановить; |
| верните значение <em>false</em>, если вы не обработали его и/или событие должно продолжаться для любых других |
| приемников события on-click.</li> |
| <li><code>{@link android.view.View.OnTouchListener#onTouch(View,MotionEvent) onTouch()}</code> — |
| этот метод возвращает логическое значение, указывающее, обработал ли ваш приемник это событие. Важно, что |
| это событие может повлечь несколько действий, следующих друг за другом. Поэтому, если вы возвращаете <em>ложь</em> при приеме |
| события нажатия, вы указываете, что вы не обработали событие и не |
| интересуетесь последующими действиями в результате этого события. Соответственно, этот метод не будет вызываться для любых других действий |
| в рамках этого события, таких как жесты или возможное действие отпускания.</li> |
| </ul> |
| |
| <p>Помните, что события аппаратных клавиш всегда попадают в отображаемый объект View, который находится в фокусе. Они отправляются, начиная с верха |
| в иерархии отображаемых объектов, затем ниже, пока не достигнут соответствующего назначения. Если ваш отображаемый объект (или дочерний объект вашего отображаемого объекта) |
| находится в фокусе, вы можете видеть, как событие перемещается сквозь метод <code>{@link android.view.View#dispatchKeyEvent(KeyEvent) |
| dispatchKeyEvent()}</code>. В качестве альтернативы к перехвату событий клавиш через отображаемый объект View можно также получать |
| все события внутри вашей операции с помощью методов <code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> |
| и <code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code>.</p> |
| |
| <p>Кроме того, размышляя о вводе текста для приложения, помните, что многие устройства поддерживают только программные методы |
| ввода. Такие методы не обязательно основаны на нажатиях клавиш. Некоторые могут использовать голосовой ввод, рукописный ввод и т. д. Даже если |
| метод ввода представлен интерфейсом, подобным клавиатуре, он обычно <strong>не</strong> приводит к запуску семейства |
| событий<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code>. Не следует создавать |
| пользовательский интерфейс, для управления которым требуется нажимать определенные клавиши, кроме случаев, когда вы хотите ограничить использование приложения только устройствами |
| с аппаратной клавиатурой. В частности, не полагайтесь на эти методы для подтверждения ввода, когда пользователь нажимает |
| клавишу «Ввод». Вместо этого используйте такие действия, как {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE}, чтобы подать методу ввода сигнал |
| о том, какой реакции ожидает приложение, чтобы он мог соответственно изменить свой пользовательский интерфейс. Избегайте предположений |
| о работе программного метода ввода и доверьте ему ввод уже отформатированного текста в ваше приложение.</p> |
| |
| <p class="note"><strong>Примечание.</strong> Система Android сначала будет вызывать обработчики событий, а затем соответствующие обработчики по умолчанию |
| из определения класса. Поэтому возврат значения <em>истина</em> из этих приемников событий будет останавливать |
| передачу события остальным приемникам событий, а также будет блокировать обратный вызов |
| обработчика событий по умолчанию в отображаемом объекте. Поэтому проверьте, что вы хотите прервать событие, когда вы возвращаете значение <em>true</em>.</p> |
| |
| |
| <h2 id="EventHandlers">Обработчики событий</h2> |
| |
| <p>Если вы создаете нестандартный компонент из отображаемого объекта, вы сможете определить несколько методов обратного вызова, |
| используемых как обработчики события по умолчанию. |
| В документе <a href="{@docRoot}guide/topics/ui/custom-components.html">Нестандартные |
| компоненты</a> можно узнать о некоторых общих обратных вызовах, используемых для обработки событий, |
| включая следующие:</p> |
| <ul> |
| <li><code>{@link android.view.View#onKeyDown}</code> — вызывается при возникновении нового события клавиши.</li> |
| <li><code>{@link android.view.View#onKeyUp}</code> — вызывается при возникновении события отпускания клавиши.</li> |
| <li><code>{@link android.view.View#onTrackballEvent}</code> — вызывается при возникновении события перемещения трекбола.</li> |
| <li><code>{@link android.view.View#onTouchEvent}</code> — вызывается при возникновении события жеста на сенсорном экране.</li> |
| <li><code>{@link android.view.View#onFocusChanged}</code> — вызывается, когда отображаемый объект получает или теряет фокус.</li> |
| </ul> |
| <p>Существует несколько других методов, о которых следует знать и которые не являются частью класса View, |
| но могут напрямую влиять на доступные вам способы обработки событий. Поэтому, управляя более сложными событиями внутри |
| макета, учитывайте и другие методы:</p> |
| <ul> |
| <li><code>{@link android.app.Activity#dispatchTouchEvent(MotionEvent) |
| Activity.dispatchTouchEvent(MotionEvent)}</code> — этот метод позволяет вашей операции {@link |
| android.app.Activity} перехватывать все события касаний перед их отправкой в окно.</li> |
| <li><code>{@link android.view.ViewGroup#onInterceptTouchEvent(MotionEvent) |
| ViewGroup.onInterceptTouchEvent(MotionEvent)}</code> — этот метод позволяет объекту {@link |
| android.view.ViewGroup} просматривать события перед их отправкой в дочерние отображаемые объекты.</li> |
| <li><code>{@link android.view.ViewParent#requestDisallowInterceptTouchEvent(boolean) |
| ViewParent.requestDisallowInterceptTouchEvent(boolean)}</code> — вызовите этот метод |
| в родительском отображаемом объекте, чтобы указать ему, что он не должен перехватывать события касания с помощью <code>{@link |
| android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)}</code>.</li> |
| </ul> |
| |
| <h2 id="TouchMode">Режим касания</h2> |
| <p> |
| Когда пользователь перемещается по пользовательскому интерфейсу с помощью клавиш перемещения или трекбола, необходимо |
| передавать фокус действующим элементам (таким как кнопки), чтобы пользователь мог видеть, |
| какой элемент будет принимать ввод. Однако, если устройство поддерживает сенсорный ввод, и пользователь |
| начинает взаимодействовать с интерфейсом, прикасаясь к его элементам, исчезает необходимость |
| выделять элементы или передавать фокус определенному отображаемому объекту. Следовательно, существует режим |
| взаимодействия, который называется «режимом касания». |
| </p> |
| <p> |
| Как только пользователь касается экрана, устройство, поддерживающее сенсорный ввод, |
| переходит в режим касания. Начиная с этого момента, фокус передается только тем отображаемым объектам, для которых |
| {@link android.view.View#isFocusableInTouchMode} имеет значение true, таким как виджеты редактирования текста. |
| Другие отображаемые объекты, которых можно коснуться, например, кнопки, не будут получать фокус при касании. Нажатие будет |
| просто запускать их приемники событий on-click. |
| </p> |
| <p> |
| В любой момент, когда пользователь нажимает клавишу перемещения или выполняет прокрутку трекболом, устройство |
| выходит из режима касания и находит отображаемый объект, которому передается фокус. Теперь пользователь может возобновить взаимодействие |
| с пользовательским интерфейсом без касания экрана. |
| </p> |
| <p> |
| Состояние режима касания поддерживается во всей системе (для всех окон и операций). |
| Чтобы узнать текущее состояние, можно вызвать |
| {@link android.view.View#isInTouchMode} и посмотреть, находится ли устройство в режиме касания. |
| </p> |
| |
| |
| <h2 id="HandlingFocus">Фокус обработки</h2> |
| |
| <p>В ответ на пользовательский ввод система обрабатывает обычное перемещение фокуса. |
| Сюда относится изменение фокуса, когда отображаемые объекты удаляются или скрываются, а также когда становятся доступными |
| новые отображаемые объекты. Отображаемые объекты сообщают о своей готовности получить фокус |
| с помощью метода <code>{@link android.view.View#isFocusable()}</code>. Чтобы изменить способность объекта View получать |
| фокус, вызовите <code>{@link android.view.View#setFocusable(boolean) setFocusable()}</code>. В режиме касания |
| можно узнать способность отображаемого объекта View получать фокус с помощью метода <code>{@link android.view.View#isFocusableInTouchMode()}</code>. |
| Для изменения вызовите <code>{@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}</code>. |
| </p> |
| |
| <p>Перемещение фокуса основано на алгоритме, который находит ближайший элемент |
| в заданном направлении. В редких случаях алгоритм по умолчанию может не совпадать |
| с поведением, которое предполагает разработчик. В этих ситуациях можно задать |
| явное переопределение с помощью следующих атрибутов XML в файле макета: |
| <var>nextFocusDown</var>, <var>nextFocusLeft</var>, <var>nextFocusRight</var>и |
| <var>nextFocusUp</var>. Добавьте один из этих атрибутов в отображаемый объект View, <em>из</em> которого |
| выходит фокус. Задайте значение атрибута для идентификатора объекта View, |
| <em>в</em> который следует передать фокус. Например:</p> |
| <pre> |
| <LinearLayout |
| android:orientation="vertical" |
| ... > |
| <Button android:id="@+id/top" |
| android:nextFocusUp="@+id/bottom" |
| ... /> |
| <Button android:id="@+id/bottom" |
| android:nextFocusDown="@+id/top" |
| ... /> |
| </LinearLayout> |
| </pre> |
| |
| <p>Обычно в этом вертикальном макете перемещение вверх из первой кнопки не должно приводить к перемещению, |
| как и перемещение вниз из второй кнопки. Теперь, когда верхняя кнопка |
| задает для нижней кнопки атрибут <var>nextFocusUp</var> (и наоборот), фокус будет перемещаться |
| циклически сверху вниз и снизу вверх.</p> |
| |
| <p>Если вы хотите объявить, что отображаемый объект в вашем пользовательском интерфейсе способен получать фокус (тогда как обычно он не может получать фокус), |
| добавьте XML-атрибут <code>android:focusable</code> в объект View в объявлении макета. |
| Установите для него значение <var>true</var>. Можно также объявить объект View, |
| способным получать фокус в режиме касания с помощью <code>android:focusableInTouchMode</code>.</p> |
| <p>Чтобы запросить передачу фокуса определенному отображаемому объекту, вызовите <code>{@link android.view.View#requestFocus()}</code>.</p> |
| <p>Чтобы перехватывать события фокуса (получать уведомления, когда отображаемый объект получает или теряет фокус), используйте метод |
| <code>{@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}</code>, |
| который обсуждается в разделе <a href="#EventListeners">Приемники событий</a> выше.</p> |
| |
| |
| |
| <!-- |
| <h2 is="EventCycle">Event Cycle</h2> |
| <p>The basic cycle of a View is as follows:</p> |
| <ol> |
| <li>An event comes in and is dispatched to the appropriate View. The View |
| handles the event and notifies any listeners.</li> |
| <li>If, in the course of processing the event, the View's bounds may need |
| to be changed, the View will call {@link android.view.View#requestLayout()}.</li> |
| <li>Similarly, if in the course of processing the event the View's appearance |
| may need to be changed, the View will call {@link android.view.View#invalidate()}.</li> |
| <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called, |
| the framework will take care of measuring, laying out, and drawing the tree |
| as appropriate.</li> |
| </ol> |
| |
| <p class="note"><strong>Note:</strong> The entire View tree is single threaded. You must always be on |
| the UI thread when calling any method on any View. |
| If you are doing work on other threads and want to update the state of a View |
| from that thread, you should use a {@link android.os.Handler}. |
| </p> |
| --> |