page.title=Eventos de entrada parent.title=Interface do usuário parent.link=index.html @jd:body

Neste documento

  1. Escutas de evento
  2. Manipuladores de evento
  3. Modo de toque
  4. Tratamento de foco

No Android, há mais de uma maneira de interceptar os eventos da interação de um usuário com o aplicativo. Ao considerar os eventos dentro da interface do usuário, a abordagem é capturar os eventos de um objeto de View específico com o qual o usuário interage. A classe View fornece os meios para fazer isto.

Dentro das várias classes View que você usará para compor o layout, é possível notar vários métodos públicos de retorno de chamada que parecem úteis para eventos de IU. Esses métodos são chamados pela estrutura do Android quando a ação respectiva ocorre neste objeto. Por exemplo, quando uma View (como um botão) é tocada, o método onTouchEvent() é chamado neste objeto. No entanto, para interceptar isto, você deve estender a classe e substituir o método. No entanto, estender todos os objetos de View para lidar com tal evento não seria algo prático. É por isso que a classe View também contém uma coleção de interfaces aninhadas com retornos de chamada que podem ser definidas com muito mais facilidade. Essas interfaces, chamadas de escutas de evento, são a sua passagem para capturar a interação do usuário com a IU.

Geralmente, as escutas de evento são usadas para escutar a interação do usuário. No entanto, há casos em que você pode querer estender uma classe View para criar um componente personalizado. Talvez você queira estender a classe {@link android.widget.Button} para deixar algo mais extravagante. Neste caso, você poderá definir os comportamentos de evento padrão para a classe usando manipuladores de evento.

Escutas de evento

Uma escuta de evento é uma interface na classe {@link android.view.View} que contém um único método de retorno de chamada. Esses métodos serão chamados pela estrutura do Android, quando a View para a qual a escuta estiver registrada for ativada pela interação do usuário com o item na IU.

Inclusos nas interfaces da escuta de evento estão os seguintes métodos de retorno de chamada:

onClick()
De {@link android.view.View.OnClickListener}. Isto é chamado quando o usuário toca no item (no modo de toque), ou atribui foco ao item com as teclas de navegação ou cursor de bola e pressiona a tecla "enter" adequada ou pressiona o cursor de bola.
onLongClick()
De {@link android.view.View.OnLongClickListener}. Isto é chamado quando o usuário toca e mantém o item pressionado (no modo de toque), ou atribui foco ao item com as teclas de navegação ou cursor de bola e mantém pressionada a tecla "enter" adequada ou o cursor de bola (por um segundo).
onFocusChange()
De {@link android.view.View.OnFocusChangeListener}. Isto é chamado quando o usuário navega no ou do item, usando as teclas de navegação ou cursor de bola.
onKey()
De {@link android.view.View.OnKeyListener}. Isto é chamado quando o usuário está com foco no item ou solta uma tecla de hardware no dispositivo.
onTouch()
De {@link android.view.View.OnTouchListener}. Isto é chamado quando o usuário realiza uma ação qualificada como um toque de evento, incluindo o pressionamento, a liberação, ou qualquer outro gesto de movimento na tela (dentro dos limites do item).
onCreateContextMenu()
De {@link android.view.View.OnCreateContextMenuListener}. Isto é chamado quando um menu de contexto está sendo construído (como resultado de um "clique longo"). Consulte a discussão sobre menus de contexto no guia do desenvolvedor Menus .

Esses métodos são os únicos habitantes de suas respectivas interfaces. Para definir um desses métodos e lidar com seus eventos, implemente a interface aninhada na atividade ou defina-a como uma classe anônima. Em seguida, passe uma instância da implementação para o respectivo método View.set...Listener(). (Ex.:, chame {@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()} e passe-o à implementação de {@link android.view.View.OnClickListener OnClickListener}.)

O exemplo abaixo mostra como registrar uma escuta de clique para um botão.

// 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);
    ...
}

Você também pode achar mais conveniente implementar OnClickListener como parte da atividade. Isto evitará carga adicional na classe e a alocação do objeto. Por exemplo:

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
    }
    ...
}

Observe que o retorno de chamada onClick() no exemplo acima não tem valor de retorno, mas outros métodos de escuta de evento podem retornar um booleano. O motivo depende do evento. Para os poucos que retornam, apresenta-se a razão:

Lembre-se de que os eventos de tecla de hardware sempre são entregues à vista atualmente em foco. Eles são enviados a partir da parte superior da hierarquia de vistas e segue à parte inferior até atingir o destino adequado. Se a vista (ou um filho da vista) estiver em foco, é possível ver o percurso do evento pelo método {@link android.view.View#dispatchKeyEvent(KeyEvent) dispatchKeyEvent()}. Como uma alternativa para capturar eventos de tecla por meio da vista, também é possível receber todos os eventos dentro da Atividade com {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()} e {@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}.

Além disso, ao pensar sobre a entrada de texto para o aplicativo, lembre-se de que vários dispositivos possuem apenas métodos de entrada de software. Tais métodos não precisam ser baseados em teclas; alguns podem usar entrada de texto por voz, por escrita e outros. Mesmo se um método de entrada apresentar uma interface parecida com teclado, geralmente ele não ativa a família de eventos {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}. Nunca deve-se compilar uma IU que exija pressionamentos de teclas específicas para ser controlada, a não ser que você queira limitar o aplicativo a dispositivos com um teclado físico. Em particular, não confie nestes métodos para validar a entrada quando o usuário pressiona a tecla de retorno; em vez disso, use ações como {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE} para sinalizar ao método de entrada como o aplicativo espera reagir para que ele possa alterar a IU de forma significativa. Evite suposições sobre como um método de entrada de software deve funcionar e confie apenas no fornecimento do texto já formatado para o aplicativo.

Observação: o Android chamará manipuladores de evento e, em seguida, manipuladores adequados padrão a partir da segunda definição de classe. Logo, retornar verdadeiro destas escutas de evento interromperá a propagação do evento para outras escutas de evento e também bloqueará o retorno de chamada para o manipulador de evento padrão na vista. Portanto, certifique-se de que quer encerrar o evento ao retornar verdadeiro.

Manipuladores de evento

Se estiver compilando um componente personalizado a partir de View, então você poderá definir vários métodos de retorno de chamada usados como manipuladores de evento padrão. No documento sobre Componentes personalizados, você aprenderá a ver alguns dos retornos de chamada usados para lidar com eventos, incluindo:

Há alguns outros métodos que você deve ter ciência que não fazem parte da classe View, mas podem ter impacto direto na maneira de lidar com os eventos. Portanto, ao gerenciar eventos mais complexos dentro de um layout, considere esses outros métodos:

Modo de toque

Quando um usuário está navegando em uma interface do usuário com teclas direcionais ou cursor de bola, é necessário fornecer foco para itens de ação (como botões) para que o usuário possa ver o que aceitará entrada. Se o dispositivo tiver capacidades de toque, no entanto, e o usuário começar a interagir com a interface por meio de toque, então não é mais necessário destacar itens ou fornecer foco para uma vista específica. Contudo, há um modo de interação chamado "modo de toque".

Para dispositivos com capacidades de toque, quando o usuário toca na tela, o dispositivo entra no modo de toque. A partir deste ponto, somente vistas que tiverem {@link android.view.View#isFocusableInTouchMode} como verdadeiro poderão ter foco, como widgets de edição de texto. Outras vistas tocáveis, como botões, não receberão foco ao serem tocadas. Em vez disso, elas simplesmente dispararão escutas de clique quando forem pressionadas.

Sempre que um usuário pressionar teclas direcionais ou rolar com o cursor de bola, o dispositivo sairá do modo de toque e encontrará uma vista para atribuir foco. Agora, o usuário pode retomar a interação com a interface do usuário sem tocar na tela.

O estado de modo de toque é mantido em todo o sistema (todas as janelas e atividades). Para consultar o estado atual, é possível chamar {@link android.view.View#isInTouchMode} para ver se o dispositivo está no modo de toque no momento.

Tratamento de foco

A estrutura lidará com a rotina de movimento de foco em resposta à entrada do usuário. Isto inclui a mudança de foco à medida que as vistas são removidas ou ocultadas, ou à medida que novas vistas se tornem disponíveis. As vistas indicam a prontidão para receber foco por meio do método {@link android.view.View#isFocusable()}. Para determinar se uma vista pode receber foco, chame {@link android.view.View#setFocusable(boolean) setFocusable()}. Quando no modo de toque, é possível consultar se uma vista permite foco com {@link android.view.View#isFocusableInTouchMode()}. É possível alterar isto com {@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}.

O movimento de foco é baseado em um algoritmo que encontra um semelhante mais próximo em uma dada direção. Em casos raros, o algoritmo padrão pode não corresponder ao comportamento pretendido do desenvolvedor. Nessas situações, é possível fornecer substituições explícitas com os seguintes atributos XML no arquivo do layout: nextFocusDown, nextFocusLeft, nextFocusRighte nextFocusUp. Adicione um desses atributos à vista a partir do foco que ela está abandonando. Defina o valor do atributo para ser o ID da vista para o foco que deve ser fornecido. Por exemplo:

<LinearLayout
    android:orientation="vertical"
    ... >
  <Button android:id="@+id/top"
          android:nextFocusUp="@+id/bottom"
          ... />
  <Button android:id="@+id/bottom"
          android:nextFocusDown="@+id/top"
          ... />
</LinearLayout>

Geralmente, neste layout vertical, navegar para cima a partir do primeiro botão não resultaria em nada, nem navegar para baixo a partir do segundo botão. Agora que o botão superior definiu o botão do fundo como nextFocusUp (e vice-versa), o foco da navegação alternará de "cima para baixo" e "baixo para cima".

Caso queira declarar uma vista como alvo de foco na IU (quando tradicionalmente não é), adicione o atributo XML android:focusable à vista, na declaração do layout. Defina o valor como verdadeiro. Também é possível declarar uma vista como alvo de foco no Modo de Toque com android:focusableInTouchMode.

Para solicitar foco a uma determinada Vista, chame {@link android.view.View#requestFocus()}.

Para ouvir eventos de foco (receber notificações quando uma vista receber ou perder foco), use {@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}, como discutido na seção Escutas de evento acima.