• Nenhum resultado encontrado

Hierarquia de view

No documento Android - Uma Visão Geral (páginas 108-115)

Sobre a plataforma Android, você define uma interface de atividades, usando uma hierarquia de view e nós ViewGroup, como mostrado no diagrama abaixo. Esta árvore de hierarquia pode ser tão simples ou complexa como você precisa que ela seja, e você pode construí-la usando o conjunto do Android de widgets e layouts pré-definidos, ou com views customizados que você mesmo cria.

A fim de fixar a árvore de hierarquia de views à tela para renderização, sua atividade deve chamar o método setContentView() e passar uma referência ao objeto nó raiz. O sistema Android recebe esta referência e usa-o para invalidar, medir e desenhar a árvore. O nó raiz da hierarquia requisita que seus nós filhos desenhem a si próprios - por sua vez, cada nó do ViewGroup é responsável por chamar cada um de seus views filhos para desenhar a si mesmos. Os filhos podem solicitar um tamanho e localização com os pais, mas o objeto-mãe tem a decisão final sobre onde e qual o tamanho que cada criança pode ter. Android analisa os elementos do layout em ordem (a partir do topo da árvore de hierarquia), instanciando os Views e adicionando-os aos seus pais. Porque estes são desenhados em ordem, se há elementos que se sobrepõem posições, o último a ser elaborado vai ficar em cima dos outros previamente elaborados para aquele espaço.

Como o Android desenha views

Quando uma atividade recebe o foco, ela será convidada a desenhar o layout. O framework Android vai lidar com o processo de elaboração, mas a atividade deve apresentar o nó raiz da sua hierarquia de layout.

Desenho começa com o nó raiz do layout. É solicitado para medir e desenhar a árvore de layout. Desenho é tratado pelo pé da árvore e renderização de cada vista que cruza a região inválida. Por sua vez, cada grupo View é responsável por solicitar a cada um dos seus filhos a ser desenhado (com o método draw()) e cada View é responsável pelo desenho de si. Como a árvore é percorrida em ordem, isso significa que os pais serão desenhados antes do que seus filhos, com irmãos elaborados na ordem em que aparecem na árvore.

Desenhar o layout é um processo de duas passagens: a passagem de medidas e uma passagem de layout. A passagem de medição é implementada com measure(int, int) e é uma passagem top-down da árvore. Cada view empurra as especificações de dimensão para baixo na árvore durante a recursividade. No final da passagem de medidas, cada View tem armazenado suas medidas. A segunda fase acontece no layout(int, int, int, int)

e também é top-down. Durante o passar, cada pai é responsável pelo posicionamento de todos os seus filhos usando os tamanhos computados na passagem de medidas.

Durante um método de retorno measure() da view, os valores getMeasuredWidth() e

getMeasuredHeight() devem ser definidos, juntamente com as de todos os descendentes da view. Os valores de medição de largura e altura da view devem respeitar as restrições impostas pelos pais da view. Isso garante que, no final da passagem de medidas, todos os pais aceitam todas as medições de seus filhos. Um pai view pode chamar measure()

mais de uma vez sobre seus filhos. Por exemplo, os pais podem medir cada filho uma vez com dimensões não especificadas para descobrir o quão grande eles querem ser, então chama measure() neles novamente com números reais, se a soma dos tamanhos dos filhos irrestrita é muito grande ou muito pequena (Ou seja, se os filhos não concordam entre si a respeito de quanto espaço cada um ganha, o pai vai intervir e estabelecer as regras na segunda passagem).

A passagem de medidas utiliza duas classes para

comunicar dimensões. A classe

View.MeasureSpec é usada por views para contar aos pais como eles querem ser medidos e posicionados. A classe base LayoutParams apenas descreve quão grandes as views querem

ser para a largura e altura. Para cada dimensão, pode especificar um dos seguintes: um número exato

FILL_PARENT, o que significa que o view quer ser tão grande quanto seu pai (menos padding)

WRAP_CONTENT, o que significa que o view quer ser grande o suficiente para colocar o seu conteúdo (mais padding).

Para dar início a um esquema, chama- se requestLayout(). Este método normalmente é chamado por uma view sobre si mesma quando se acredita que é possível não caber mais dentro de seus limites atuais.

Há subclasses de LayoutParams para diferentes subclasses de ViewGroup. Por exemplo, RelativeLayout tem a sua própria subclasse de LayoutParams, que inclui a capacidade de centralizar os filhos horizontalmente e verticalmente.

MeasureSpecs são usados para empurrar os requisitos para baixo da árvore de pai para filho. Um MeasureSpec pode estar em um dos três modos:

NÃO ESPECIFICADO: Isto é usado por um dos pais para determinar a dimensão desejada de um filho View. Por exemplo, um LinearLayout pode chamar measure() em seu filho com a altura indefinida e uma largura de exatamente 240.

EXATAMENTE: Este é usado pelos pais para impor um tamanho exato sobre a criança. A criança deve usar esse tamanho, e garante que todos os seus descendentes se encaixem dentro desse tamanho.

NO MÁXIMO: Este é usado pelos pais para impor um tamanho máximo para a criança. A criança deve garantir que ele e todos os seus descendentes vão caber dentro deste tamanho.

Layout

A maneira mais comum para definir o seu layout e expressar a hierarquia de view é com um arquivo de layout XML. XML oferece uma estrutura legível para o layout, muito parecido com HTML. Cada elemento em XML é ou um View ou ViewGroup (ou descendentes dos mesmos). Objetos view são folhas da árvore, objetos ViewGroup são ramos da árvore.

O nome de um elemento XML é respectivo para a classe Java que representa. Assim, um elemento <TextView> cria um na sua interface do usuário, e um elemento <LinearLayout> cria um ViewGroup. Quando você carregar um recurso de layout, o sistema Android inicializa esses objetos em tempo de execução, correspondentes aos elementos em seu layout.

Por exemplo, um layout simples vertical, com um text view e um botão parece com este:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_height="fill_parent"

android:orientation="vertical"> <TextView android:id="@+id/text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello, I am a TextView"/> <Button android:id="@+id/button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello, I am a Button"/> </LinearLayout>

Observe que o elemento LinearLayout contém o TextView e o Botão. Você pode aninhar outro LinearLayout (ou outro tipo de grupo de exibição) aqui dentro, para alongar a hierarquia de view e criar um layout mais complexo.

Dica: Você também pode desenhar View e ViewGroups em código Java, utilizando

métodos para inserir dinamicamente novos objetos View e ViewGroup.

Há uma variedade de maneiras em que você pode formatar os seus view. Usando mais tipos diferentes de grupos de exibição, você pode estruturar views herdados e view groups em um número infinito de maneiras. Alguns view groups pré-definidos oferecidas pelo Android (chamando layouts) incluem LinearLayout, RelativeLayout, TableLayout, GridLayout e outros. Cada um oferece um conjunto exclusivo de parâmetros de layout que são usados para definir as posições das views herdadas e a estrutura de layout.

To learn about some of the different kinds of view groups used for a layout, read . Para saber mais sobre alguns dos diferentes tipos de grupos de vista usado para um layout, leia os objetos de layout comum .

Widgets

Um widget é um objeto View que serve como uma interface de interação com o usuário. Android fornece um conjunto de widgets plenamente implementadas, como botões, caixas de seleção, e os campos de entrada de texto, assim você pode construir rapidamente sua interface do usuário. Alguns widgets fornecidos pelo Android são mais complexos, como um selecionador de data, um relógio, e controles de zoom. Mas você não está limitado aos tipos de elementos fornecidos pela plataforma Android. Se você quiser fazer algo mais personalizado e criar seus próprios elementos, pode, através da

definição de seu objeto View próprio ou através da extensão e combinação de elementos existentes.

Eventos UI

Uma vez que você adicionou alguns views/widgets para a interface do usuário, você provavelmente quer saber sobre a interação do usuário com eles, para que você possa executar ações. Para ser informado de eventos de interface, você precisa fazer uma de duas coisas:

Definir um receptor de evento e registrá-lo com a view. Muitas vezes, é assim que você vai receber os eventos. A classe View contém uma coleção de interfaces aninhadas nomeadas <something> Listener, cada um com um método de retorno de chamada On <something>(). Por exemplo, View.OnClickListener (para lidar com os "cliques" na View), View.OnTouchListener (para lidar com eventos de tela de toque em uma exibição), e View.OnKeyListener (para lidar com teclas pressionadas no dispositivo dentro de uma View). Então se você quer sua View para ser notificado quando ela é "clicada" (como quando um botão é selecionado), implemente OnClickListener e defina o seu método de retorno

onClick() (onde você executar a ação após o clique), e registra-o para a View com setOnClickListener().

Substituir um método de retorno existente para a View. Isto é o que você deve fazer quando você implementou sua própria classe View e quer receber eventos específicos que ocorrem dentro dele. Exemplificando eventos você pode manipular inclusão quando a tela é tocada (onTouchEvent()), quando o trackball é movido (onTrackballEvent()), ou quando uma tecla no dispositivo é pressionada (onKeyDown()). Isso permite que você defina o comportamento padrão para cada evento dentro da sua View personalizada e determinar se o evento deve ser transmitido para alguma outra View filho. Novamente, essas são chamadas de retorno para a classe View, assim, sua única chance de defini-los é quando você cria um componente personalizado.

Menus

Os menus de aplicativos são outra parte importante da interface do usuário de um aplicativo. Menus oferecem uma interface confiável, que revela funções de aplicativos e configurações. O menu de aplicativos mais comuns é revelado, pressionando a tecla MENU no dispositivo. No entanto, você também pode adicionar menus de contexto,

que podem ser revelados quando o usuário pressiona e mantém pressionado em um item.

Os menus também são estruturados usando uma hierarquia View, mas você não define essa estrutura por si mesmo. Em vez disso, você define métodos de retorno como

onCreateOptionsMenu() ou onCreateContextMenu() para a sua atividade, e declara os itens que você deseja incluir em seu menu. Em momento oportuno, o Android irá criar automaticamente a necessária hierarquia View para o menu e desenhar cada um dos seus itens de menu na mesma.

Menus também lidam com seus próprios eventos, por isso não há necessidade de registrar eventos listeners sobre os itens do seu menu. Quando um item no seu menu é selecionado, o método onOptionsItemSelected() ou onContextItemSelected() será chamado pelo framework.

E, assim como o layout do aplicativo, você tem a opção de declarar os itens para seu menu em um arquivo XML.

No documento Android - Uma Visão Geral (páginas 108-115)

Documentos relacionados