Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

sexta-feira, 11 de março de 2011

Interface de Usuários - Manipulando eventos

No Android, existe mais de uma maneira de interceptar eventos de interação de usuário em sua aplicação. Quando consideramos eventos dentro de sua interface de usuário, a abordagem deve ser a de capturar os eventos do objeto de View específica na qual o usuário está interagindo. A classe View provê todo o necessário para fazê-lo.

Dentro das várias classes View que vão compor o seu layout, você vai notar diversos métodos públicos que contém eventos muito úteis para a interface. Esses métodos são chamados pelo framework Android quando a ação correspondente ocorre no objeto. Por exemplo, quando uma View (como um botão) é tocado, o método onTouchEvent() é chamado no objeto. Contudo, para que possa ser interceptado, você deve extender a classe e fazer o override do método. Mas, extender cada um dos objetos View seria impraticável. É por esse motivo que a classe View também contém uma coleção de interfaces aninhadas com callbacks que você pode definir de maneira muito mais fácil. Essas interfaces, chamadas event listeners, são seu ticket para capturar quaisquer interações de usuários dentro de sua interface.

Mesmo que usualmente você use os event listeners mais comuns para fazer a interação da aplicação com o usuário, chegará um momento em que você vai querer extender a classe View para criar um componente customizado. Talvez você queira extender uma classe Button para fazer algo mais bonito de se ver. Nesse caso, você será capaz de definir eventos padrão de comportamento para sua classe usando os event handlers.

Event Listeners

Um event listener é uma interface da classe View que contém um método simples de callback. Esse método pode ser chamado pela framework Android quando a View à quando o listener está registrado é chamado por uma interação de usuário com um item da interface.

Incluído nas interfaces de event listener estão os seguintes métodos callback:

onClick()
Vem de View.OnClickListener. É chamado quando o usuário toca o item (quando estiver em modo de toque) ou foca o item através de teclas de navegação ou trackball e pressiona o botão de enter correspondente ou pressiona o trackbak (que também serve como enter).

onLongClick()
Vem de View.OnLongClickListener. É chamado quando o usuário toca um item e o segura (quando estiver em modo de toque) ou foca o item através de teclas de navegação ou trackball e pressiona o botão de enter correspondente e o segura ou pressiona o trackbak por pelo menos um segundo.

onFocusChange()
Vem de View.OnFocusChangeListener. É chamado quando o usuário navega para dentro ou para fora de um item, usando as teclas de navegação ou trackball.

onKey()
Vem de View.OnKeyListener. É chamado quando o usuário foca em um item e pressiona ou solta uma tecla no dispositivo. Exemplo: quando se está escrevendo uma mensagem, você pode tocar no botão virtual (ou físico) da letra A e, ao soltá-lo, a letra A é mostrada na tela.

onTouch()
Vem de View.OnTouchListener. É chamado quando o usuário performa uma ação qualificada como um evento de toque, incluindo pressionar, soltar ou qualquer movimento de gesto na tela (dentro dos limites do item).

onCreateContextMenu()
Vem de View.OnCreateContextMenuListener. É chamado qunado um menu de contexto está sendo criado (como resultado de um long click).

Esses métodos habitam apenas suas respectivas interfaces. Para definir um ou mais desses métodos para interceptar seus eventos, implemente a interface aninhada em sua Atividade e a defina como uma classe anônima. Então, passe uma instância de sua implementação para o método respectivo View.set[]Listener (onde [] pode ser substituido por OnClick, OnKey, etc, gerando setOnClickListener, setOnKeyListener, etc).

O exemplo abaixo mostra como registrar um listener onClick para um botão.

// Cria uma implementação anônima de OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
    public void onClick(View v) {
      // faz algo quando o botão é clicado
    }
};
protected void onCreate(Bundle savedValues) {
    ...
    // Cria o botão para o layout
    Button button = (Button)findViewById(R.id.corky);
    // Registra o listener onClick listener com a implementação acima
    button.setOnClickListener(mCorkyListener);
    ...
}
Você vai achar mais conveniente implementar um OnClickListener como parte de sua atividade. Dessa maneira você evitará uma classe extra apenas para carregar os listeners. Por exemplo:

public class ExampleActivity extends Activity implements OnClickListener {
    protected void onCreate(Bundle savedValues) {
        ...
        Button button = (Button)findViewById(R.id.corky);
        button.setOnClickListener(this);
    }
    // Implementa o callback OnClickListener
    public void onClick(View v) {
      // Faz algo quando o botão é clicado
    }
    ...
}
Note que o callback onClick() do exemplo acima não tem valor de retorno, mas alguns outros event listeners devem retornar um valor booleano, dependendo do evento chamado.

onLongClick() e onClick()
Retorna um booleano indicando se você consumiu o evento e se ele deve ser continuado. Ou seja, retorna true para indicar que o processo já foi interceptado e que deve ser terminado ou retorna false se não foi interceptado e o evento deve continuar.

onTouch()
Retorna um booleano indicando se seu listener já consumiu o evento. A coisa importante aqui é que o evento pode ter multiplas ações que seguem uma à outra. Então, se for retornado false quando um evento for recebido é indicado que você não consumiu o evento e que você não está interessado nos eventos subsequentes a partir desse evento.

Lembre-se que os eventos são sempre disponibilizados para a View em foco no momento. Eles são despachados começando do topo da hierarquia de View até chegar ao destino apropriado. Se sua View (ou um filho de uma View) perde o foco, então você poderá ver toda o histórico dos eventos usando o método dispatchKeyEvent(). Como uma alternativa a captura de eventos de tecla através de sua View, você também pode receber todos os eventos dentro de sua atividade usando onKeyDown() e onKeyUp().

Event Handlers

Se você estiver construindo um componente customizado para sua View, então você terá de definir os métodos de callback a serem usados como handlers padrão para o evento. Quando chegarmos no tópico de construção de componentes customizados, veremos como fazer essa configuração.

Modo de Toque

Quando um usuário está navegando pela interface com teclas direcionais ou trackball, é necessário dar foco aos itens que contém ações (como botões) para que o usuário possa saber com quais itens pode interagir e que oferecem ação. Se o seu dispositivo tem capacidade de toque, contudo, o usuário começa a interagir com a interface bastando tocá-la, não sendo mais necessário dar foco a esses itens. Esse modo de interação é chamado de touch mode.

Para um dispositivo de toque, uma vez que o usuário toque a tela o dispositivo entrará em modo de toque. A partir desse ponto em diante, apenas as Views para as quais o método isFocusableInTouchMode estiver como true é que poderão ser focados, como edição de texto em widgets. Outras Views que são tocáveis, como botões, não obterão foco quando tocadas; elas simplesmente vão disparar os listeners onClick quando pressionados.

A qualquer momento que o usuário toque as teclas direcionais ou ande pela tela com um trackball, o dispositivo vai sair do modo de toque e tentará encontrar uma View que possa gerenciar focos.

O modo de toque é mantido pelo sistema. Para verificar se ele está em modo toque, basta chamar isInTouchMode para checar.

Gerenciando Foco

A framework vai gerenciar rotinas de focos em resposta às entradas do usuário. Isso inclui mudar o foco quando as Views são removidas ou escondidas ou quando novas Views se tornarem disponíveis. Views indicam a sua capacidade de ter foco através do método isFocusable(). Para mudar essa característica na View, você pode chamar setFocusable(). Quando estiver em modo toque, você poderá pesquisar para saber se a View aceita foco com isFocusableInTouchMode(). Você pode mudar essa característica usando setFocusableInTouchMode().

Normalmente o Android entende qual é o próximo item a ter foco, verificando qual o item mais próximo. No entanto, em casos raros, é necessário que você insira a sequência a ser seguida. Nesse caso, você pode prover atributos no layout do arquivo usando tags como nextFocusDown, nextFocusLeft, nextFocusRight e nextFocusUp. Exemplo abaixo:

<LinearLayout
    android:orientation="vertical"
    ... >
  <Button android:id="@+id/top"
          android:nextFocusUp="@+id/bottom"
          ... />
  <Button android:id="@+id/bottom"
          android:nextFocusDown="@+id/top"
          ... />
</LinearLayout>
Com o código acima, veja que o foco vai do botão top para o botão bottom e vice-versa.

3 comentários:

Leila disse...

muito bom a explicação.

Anderson Souza disse...

Eu consigo capturar fora de activitys? ou seja, pegar qualquer toque na tela.

Anderson Souza disse...

Eu consigo capturar fora de activitys? ou seja, pegar qualquer toque na tela.

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...