MENU Mário Valney

Aula 6: Como escrever o layout da minha aplicação?

Curso de Android 07 de junho de 2015 2 comentários
Curso de Android
  • 07 - 06 - 15
  •        
  • 2

Veja todas as aulas aqui.

E ae galera! Tudo bem?
Aula passada falamos de como criar nossa User Interface, ou seja, basicamente as telas. Nela, vimos que existem as Views (e os grupos de Views) e que elas são as responsáveis por criar os elementos visuais. Vimos também que isso tudo pode ser escrito em XML, nos arquivos de layout.

Então hoje nossa missão é essa: aprender como escrever os layouts da nossa aplicação usando apenas XML!

Como criar um layout?

Um layout define a estrutura visual da sua UI (tanto para uma Activity, quanto para uma widget).

Há duas formas de escrever um layout:

  • Instanciando os elementos do layout em tempo de execução: suas aplicações podem criar Views e ViewGroups, além de manipular suas propriedades em tempo de execução.
  • Declarando os elementos no arquivo XML: o Android provê uma estrutura forte de XML declarando as classes e subclasses das Views, dessa forma você pode criar o layout usando apenas essa linguagem nos arquivos de resource

E claro que você pode usar as duas formas simultaneamente, né? :D

Por que não fazemos tudo em tempo de execução então?

Bem… a maior vantagem de declarar seus elementos visuais num arquivo XML é que você separa a aparência da sua aplicação do código que a gerencia. Sem falar que você possui a liberdade de adaptação dos recursos, como já falamos antes. Assim, criamos layouts adaptáveis a cada tipo de tela, orientação e até linguagem, caso seja necessário.

Além disso, fica muito mais fácil de visualizar a hierarquia dos elementos da sua UI, o que facilita também achar erros e fazer o debug.

Características do vocabulário XML

Não irei falar sobre a linguagem em si. Caso você queira dar uma estudada sobre XML, veja esse link da Wikipédia (web developers devem estar felizes, por essa linguagem ser muito natural pra gente).

Vamos lá então: em geral, o vocabulário usado segue muito perto da estrutura e dos nomes das classes e métodos das Views. Na verdade, a correspondência é tão direta, que as vezes fica fácil adivinhar que método corresponde a que atributo XML e vice-versa, todavia as vezes não é tão direto. Por exemplo, o elemento EditText possui um atributo chamado text, que serve para indicarmos qual o texto desse elemento. Já o método da classe não é o “text”, mas sim “setText”, resultando em: EditText.setText().

Não é tão óbvio, mas também nada de outro mundo, concordam?

Escrevendo o XML

Novamente, Web Developers levam vantagem aqui: a forma de escrever o seu layout é muito parecida com a estruturação de uma página em HTML.

Cada layout deve possuir um único elemento raiz (root element), que deve ser uma ViewGroup (ou View), que possui o atributo xmlns:android (com o namespace do Android, como você pode ver no exemplo mais abaixo ou no final desse artigo). Dentro dessa raiz, você pode adicionar os elementos de layout e widgets que necessitar, criando assim a hierarquia de elementos da sua UI.

Lembra do arquivo fragment_main.xml da aula passada?

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity$PlaceholderFragment">
 
    <ListView
        android:id="@+id/list_last_posts"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
 
</FrameLayout>

O objeto FrameLayout é o elemento raiz e dentro dele temos um único filho: uma ListView.

Com tudo isso pronto, salvamos o arquivo .XML na pasta /res/layout/ e já podemos chamá-lo no código, quando necessário. Mas já falamos disso na aula passada (que tal uma revisão?).

Atributos

Cada objeto View ou ViewGroup suporta uma variedade de atributos. Alguns são particulares, como “textSize” para o elemento “TextView”, outros são herdados para todas as Views, como o atributo “ID”.

Além desses, temos os parâmetros de layout, que descrevem a orientação do objeto, por exemplo.

O atributo “ID”

Cada View deve ter um inteiro como ID. Esse ID deve ser único e serve para identificar a View dentro da árvore.

Quando o aplicativo é compilado, esse ID é referenciado como um inteiro, mas quando estamos escrevendo o XML, geralmente atribuímos uma string ao atributo ID, dessa forma:

android:id="@+id/list_last_posts"

O @ (arroba) indica que o XML Parse deve identificar essa string como um ID de um resource. O símbolo de mais significa que esse é um novo nome de recurso e deve ser armazenado como tal (lembra da class R, que falei no meu artigo sobre resources?).

Dessa forma, se formos nos referir a um ID para chamá-lo e não para criá-lo não usamos o símbolo de mais, mas sim a palavra “android”:

android:id="@android:id/list_last_posts"

Mas confesso que nunca precisei usar dessa forma. Contudo, conhecimento nunca é demais, né?

Nas aulas anteriores já vimos como acessar elementos dos recursos através do código, mas mais uma vez gostaria de dar um exemplo:

ListView minhaLista = (ListView) findViewById(R.id.list_last_posts);

Usamos isso geralmente no método onCreate() e o padrão seria:

ClasseDaView nome_da_variavel = (ClasseDaView) findViewById(R.id.id_da_view);

Atributos de Layout

Os atributos XML com o nome layout_algumacoisa definem parâmetros de layout para as Views, que são apropriados para os Grupos (ViewsGroups) que residem.

Cada ViewGroup implementa uma classe filha (nested class) que estende ViewGroup.LayoutParams. Essa subclasse contem as propriedades que definem o tamanho e a posição de cada View dentro dela.

Na imagem abaixo, podemos ver um exemplo de como um ViewGroup pai define parâmetros de layout para as Views e ViewGroup filhas:

Visualização da árvore das Views e os Parâmetros de Layout herdados de cada ViewGroup
Visualização da árvore das Views e os Parâmetros de Layout herdados de cada ViewGroup

Há diversas sintaxes de parâmetros de layout de acordo com o ViewGroup pai e a View filha. Cada View ou ViewGroup filha deve definir os seus LayoutParams que são apropriados para o ViewGroup pai, apesar de também poder definir LayoutParams para suas próprias filhas. É um pouco complicado de começo, mas consultando a documentação de cada elemento da View, quando for utiliza-lo já facilita bastante.

Largura e Altura

Todos os ViewGroups implementam uma largura e uma altura (“layout_width” e “layout_height”), as quais você pode definir com medidas exatas ( dificilmente você vai querer isso :D ) ou usando essas duas constantes:

  • wrap_content: o tamanho da View será exatamente o tamanho do seu conteúdo.
  • match_parent (também chamado de “fill_parent” antes da API 8): faz com que a View seja tão grande quanto seu pai permitir.

As dimensões que você pode usar para indicar a largura e altura exatas pode ser encontrada nesse link da documentação, mas usar “wrap_content” ou “match_parent” será sempre uma opção melhor.

Posição no Layout

Devemos imaginar uma View como um retângulo: ela possui largura, altura e sua posição é dada pela distância do topo e da lateral esquerda. Nada novo até aí, né?

É possível conseguir sua posição usando os métodos getLeft() e getTop(). Esses métodos retornam os valores da distância à esquerda (X) e ao topo (Y), respectivamente.

Só esses dois métodos já seriam o bastante, mas como a galera do Android é muito gente boa, temos também o método getRight(), equivalente ao getLeft() + getWidth() e o método getBottom(), equivalente ao getTop() + getHeight(). Legal, né?

Na documentação, você encontra também os métodos e mais detalhes para o tamanho, padding e margens. Recomendo dar uma lida, porque agora vamos dar uma olhada mais a fundo na sintaxe de escrita do XML.

Sintaxe de um arquivo de Layout

Já vimos como escrever o seu Layout (e um exemplo disso) e falamos também dos atributos e do vocabulário XML empregado pelo Android. Agora iremos ver um pouco mais detalhadamente a escrita do XML de um arquivo de Layout (layout resource).

<?xml version="1.0" encoding="utf-8"?>
<ViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@[+][package:]id/resource_name"
    android:layout_height=["dimension" | "fill_parent" | "wrap_content"]
    android:layout_width=["dimension" | "fill_parent" | "wrap_content"]
    [ViewGroup-specific attributes] >
    <View
        android:id="@[+][package:]id/resource_name"
        android:layout_height=["dimension" | "fill_parent" | "wrap_content"]
        android:layout_width=["dimension" | "fill_parent" | "wrap_content"]
        [View-specific attributes] >
        <requestFocus/>
    </View>
    <ViewGroup >
        <View />
    </ViewGroup>
    <include layout="@layout/layout_resource"/>
</ViewGroup>

Linha por linha

– A primeira linha é padrão, use-a:

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

– Logo em seguida, temos o elemento raiz (root element), conforma falamos lá no começo. Só podemos ter um e deve ser um ViewGroup, exceto no caso do arquivo de layout descrever apenas uma única View, como no nosso list_item_last_posts.xml, por exemplo.

Alguns exemplos seriam: LinearLayout, RelativeLayout e FrameLayout.

Esse elemento deve possuir os atributos ID, layout_height e layout_width, conforma já falamos. Para os demais valores de cada ViewGroup, veja a documentação correspondente.

– Como filha da ViewGroup, podemos ter Views, que são os componentes individuais da UI, comumente chamadas de “widgets”. Alguns exemplos são: TextView, Button e CheckBox.

Igualmente, as Views devem possuir os atributos para ID, largura e altura, além dos atributos individuais de cada uma.

– Um elemento representando uma View pode possuir um elemento vazio chamado <requestFocus>, que dá à View o foco inicial na tela. Apenas um elemento por arquivo pode contê-lo.

– Podemos incluir outros arquivos de layout utilizando o elemento <include>. Esse elemento deve possuir (obrigatoriamente) o atributo layout, que referencia o arquivo que deve ser incluído, além de poder possuir os atributos de ID, layout_width e layout_height, que sobrescrevem o ID, a largura e a altura do elemento raiz do layout incluído, respectivamente.

<include layout="@layout/layout_resource"/>

– Por último, podemos usar o elemento <merge>, como uma elemento raiz alternativo. Um exemplo de uso é quando sabemos que esse arquivo vai ser incluído por outro e não há necessidade de termos um ViewGroup a mais como raiz. Mais detalhes aqui.

Conclusão e referências

E é isso, pessoal! (clique aqui e escute essa música enquanto lê)

Mais uma aula do nosso curso e infelizmente não abrimos novamente o Android Studio, mas como o Daniel San aprendeu pintando paredes: “Primeiro aprender a ficar em pé, depois aprender a voar”.

Então dê uma lida na documentação, abra seu Android Studio e com o que já vimos na aula passada, você conseguirá criar layouts e testar para ver como eles ficam no seu celular.

Compartilhe para espalhar o conhecimento e não esqueça de deixar suas dúvidas e comentários logo abaixo. Abraços e até a próxima (que está bem perto)!

Por favor, considere desativar o AdBlock

Não perca nenhuma novidade do nosso Curso!

Não se preoculpe, não enviaremos muitos e-mails, nem mostraremos seu e-mail para ninguém. Dúvidas?


Deixe seu comentário! Dúvida sobre como comentar
ou vai postar código? Leia antes.