Layouts Parte do Android Jetpack.
O layout define a estrutura de uma interface do usuário no aplicativo, como acontece na atividade.
Todos os elementos do layout são criados usando a hierarquia de objetos View
e
ViewGroup
. A View
geralmente
desenha algo que o usuário pode ver e com que pode interagir. Já um ViewGroup
é um
contêiner invisível que define a estrutura do layout para View
e outros
objetos ViewGroup
, como pode ser visto na figura 1.

Figura 1. Ilustração de uma hierarquia de visualização, que define o layout de uma IU.
Os objetos View
geralmente são chamados de "widgets" e podem ser uma das muitas
subclasses, como Button
ou TextView
. Os
objetos ViewGroup
geralmente são chamados de layouts e podem ser de um dos muitos tipos que
fornecem uma estrutura de layout diferente, como LinearLayout
ou
ConstraintLayout
.
Um layout pode ser declarado de duas maneiras:
- Declarar elementos da IU em XML. O Android fornece um vocabulário XML
direto que corresponde às classes e subclasses de visualização, como as de widgets e
layouts.
Também é possível usar o Layout Editor do Android Studio para criar o layout XML usando uma interface de arrastar e soltar.
- Instanciar elementos do layout no momento da execução. O aplicativo pode criar objetos View e ViewGroup (e processar suas propriedades) programaticamente.
Ao declarar a IU no XML, é possível separar a apresentação do seu aplicativo do código que controla o comportamento dele. O uso de arquivos XML também facilita conseguir layouts diferentes para diferentes orientações e tamanhos de tela. Isso é discutido em Compatibilidade com diferentes tamanhos de tela.
A biblioteca do Android oferece flexibilidade para usar um ou ambos os métodos para criar a IU do seu aplicativo. Por exemplo, é possível declarar os layouts padrão do aplicativo em XML e, em seguida, modificar o layout no momento da execução.
Dica: para depurar o layout no momento da execução, use a ferramenta Layout Inspector.
Programação do XML
Usando o vocabulário XML do Android, é possível projetar rapidamente layouts de IU e os elementos de tela intrínsecos, do mesmo modo que se cria páginas Web em HTML - com uma série de elementos aninhados.
Cada arquivo de layout deve conter exatamente um elemento raiz, que deve ser um objeto View ou ViewGroup. Com o elemento raiz definido, é possível adicionar objetos ou widgets de layout extras como elementos filho para construir gradualmente uma hierarquia de View que define o layout. Por exemplo, veja um layout XML que usa um LinearLayout
vertical para conter um TextView
e um Button
:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_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>
Após declarar o layout no XML, salve o arquivo com uma extensão .xml
no diretório res/layout/
do projeto do Android para compilá-lo adequadamente.
Veja mais informações sobre a sintaxe de um arquivo XML de layout no documento Recursos de layout.
Carregamento do recurso XML
Ao compilar o aplicativo, cada arquivo de layout XML é compilado em um
recurso View
. Deve-se carregar o recurso de layout do código do aplicativo na
implementação de callback Activity.onCreate()
.
Para isso, chame
,
passando a referência para o recurso de layout na forma:
setContentView()
R.layout.layout_file_name
.
Por exemplo, se o layout XML for salvo como main_layout.xml
, será necessário carregá-lo
para a Activity desta forma:
Kotlin
fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.main_layout) }
Java
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }
O método de callback onCreate()
na Atividade é chamado pelo framework do Android quando
ela é iniciada. Veja a discussão sobre ciclos de vida no documento
Atividades.
Atributos
Cada objeto View e ViewGroup aceita uma variedade própria de atributos XML.
Alguns atributos são específicos de um objeto View (por exemplo, TextView aceita o atributo textSize
),
mas esses atributos também são herdados de objetos View que possam estender essa classe.
Alguns são comuns a todos os objetos View porque são herdados da classe View raiz (como
o atributo id
). Além disso, outros são considerados "parâmetros do layout", que são
atributos que descrevem determinadas orientações de layout do objeto View, conforme definido pelo objeto
ViewGroup pai daquele objeto.
ID
Qualquer objeto View pode ter um ID de número inteiro associado para identificar exclusivamente o View dentro da árvore.
Ao compilar o aplicativo, esse ID é referenciado como um número inteiro, mas normalmente é
atribuído no arquivo XML do layout como uma string, no atributo id
.
É um atributo XML comum a todos os objetos View
(definido pela classe View
) e você o usará com frequência.
A sintaxe de um ID, dentro de uma tag XML, é:
android:id="@+id/my_button"
Um símbolo de arroba (@) no início da string indica que o analisador XML deve analisar e expandir o restante
da string de ID e identificá-la como um recurso de ID. O símbolo de mais (+) significa que é um novo nome de recurso que precisa
ser criado e adicionado aos recursos (no arquivo R.java
). Há diversos outros recursos de ID
oferecidos pelo framework do Android. Ao referenciar um ID de recurso do Android, não é necessário ter o símbolo de mais,
mas deve-se adicionar o namespace do pacote android
da seguinte maneira:
android:id="@android:id/empty"
Com o namespace do pacote android
em vigor, podemos referenciar um ID da classe de recursos de android.R
em vez de um da classe de recursos locais.
Para criar visualizações e referenciá-las a partir do aplicativo, um modo padrão comum é:
- Definir uma visualização/um widget no arquivo de layout e atribuir um ID exclusivo a ela/ele:
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>
- Em seguida, criar uma instância do objeto de visualização e capturá-la do layout
(normalmente no método
):onCreate()
Kotlin
val myButton: Button = findViewById(R.id.my_button)
Java
Button myButton = (Button) findViewById(R.id.my_button);
Definir IDs para objetos de visualização é importante ao criar um RelativeLayout
.
Em um layout relativo, visualizações irmãs podem definir o layout relativo para outra visualização irmã,
referenciada pelo ID exclusivo.
Os IDs não precisam ser exclusivos por toda a árvore, mas devem ser exclusivos dentro da parte da árvore em que você está procurando (que pode, com frequência, ser toda a árvore, portanto, é preferível ser totalmente exclusivo sempre que possível).
Observação: com o Android Studio 3.6 e mais recentes, o
recurso de vinculação de visualizações pode substituir
chamadas de findViewById()
e fornece segurança de tipo no tempo de compilação para o
código que interage com as visualizações. Use a vinculação de visualizações em vez de
findViewById()
.
Parâmetros do layout
Os atributos do layout XML chamados layout_something
definem
parâmetros de layout para o View apropriados para o ViewGroup em que reside.
Cada classe ViewGroup implementa uma classe aninhada que estende ViewGroup.LayoutParams
. Essa subclasse
contém tipos de property que definem o tamanho e a posição de cada visualização filha, conforme
necessário para o grupo de visualizações. Como se pode ver na figura 2, um grupo
de visualizações pai define parâmetros de layout para cada visualização filha (incluindo o grupo de visualizações filhas).

Figura 2. Visualização de uma hierarquia de exibições com parâmetros de layout associados a cada uma delas.
Cada subclasse LayoutParams tem a própria sintaxe para definir valores. Cada elemento filho deve definir LayoutParams apropriados para o pai, embora possa também definir diferentes LayoutParams para os próprios filhos.
Todos os grupos de visualizações contêm largura e altura (layout_width
e layout_height
) e cada visualização é obrigatória para defini-las. Muitos
LayoutParams também contêm margens e bordas opcionais.
É possível especificar largura e altura com medidas exatas, embora não seja recomendável na maioria dos casos. Em geral, usa-se uma destas constantes para definir a largura e a altura:
- wrap_content instrui a exibição a redimensionar de acordo com as dimensões exigidas pelo conteúdo.
- match_parent instrui sua visualização a assumir o maior tamanho permitido pelo grupo de visualizações parental.
Em geral, a especificação de largura e altura de um layout com unidades absolutas, como pixels, não é recomendada. Em vez disso, o uso de medidas relativas como unidades de pixel de densidade independente (dp), wrap_content ou match_parent é uma abordagem melhor, porque ajuda a garantir que o app exiba o conteúdo adequadamente nos diversos tamanhos de tela de dispositivos. Os tipos de medidas aceitos são definidos no documento Recursos disponíveis.
Posição do layout
A forma geométrica de uma visualização é um retângulo. As visualizações têm uma localização, expressa como um par de coordenadas esquerda e superior, além de duas dimensões, expressas como largura e altura. A unidade de localização e de dimensões é o pixel.
É possível recuperar a localização de uma visualização chamando os métodos
getLeft()
e getTop()
. O primeiro retorna a coordenada esquerda, ou X,
do retângulo que representa a visualização. O último retorna a
coordenada superior, ou Y, do retângulo que representa a visualização. Esses métodos
retornam a localização da visualização em relação ao pai correspondente. Por exemplo,
quando getLeft()
retorna 20, significa que a visualização se localiza 20 pixels à
direita da borda esquerda do seu pai direto.
Além disso, diversos métodos de conveniência são oferecidos para evitar cálculos
desnecessários, chamados getRight()
e getBottom()
.
Esses métodos retornam as coordenadas das bordas direita e inferior do
retângulo que representa a visualização. Por exemplo, chamar getRight()
é semelhante ao seguinte cálculo: getLeft() + getWidth()
.
Tamanho, preenchimento e margens
O tamanho de uma visualização é expresso por largura e altura. As visualizações, na verdade, têm dois pares de valores de largura e altura.
O primeiro par é conhecido como largura medida e
altura medida. Essas dimensões definem o tamanho que a visualização terá
dentro do parental. As
dimensões medidas podem ser conseguidas chamando getMeasuredWidth()
e getMeasuredHeight()
.
O segundo par é simplesmente conhecido como largura e altura ou,
às vezes, largura do desenho e altura do desenho. Essas
dimensões definem o tamanho real da visualização na tela, na hora do desenho e
após o layout. Esses valores podem diferir da largura e
da altura medidas. Os valores de largura e altura podem ser conseguidos chamando
getWidth()
e getHeight()
.
Para medir as dimensões, a visualização leva em conta o preenchimento. O padding
é expresso em pixels para a esquerda, a direita e as partes superior e inferior da visualização.
O padding pode ser usado para compensar o conteúdo da visualização por um número específico
de pixels. Por exemplo, um padding à esquerda de 2 empurrará o conteúdo da visualização em
2 pixels para a direita da borda esquerda. O preenchimento pode ser definido usando o método
setPadding(int, int, int, int)
e consultado chamando
getPaddingLeft()
, getPaddingTop()
,
getPaddingRight()
e getPaddingBottom()
.
Mesmo que cada visualização possa definir um padding, ela não fornece nenhuma compatibilidade
com margens. No entanto, os grupos de visualizações oferecem essa compatibilidade. Consulte
ViewGroup
e
ViewGroup.MarginLayoutParams
para ver mais informações.
Para mais informações sobre dimensões, consulte Valores de dimensões.
Layouts comuns
Cada subclasse da classe ViewGroup
fornece um modo exclusivo de exibir
as visualizações aninhadas dentro dela. Abaixo estão alguns dos tipos de layout mais comuns criados
na plataforma Android.
Observação: embora você possa aninhar um ou mais layouts em outro layout para conseguir o design de IU, procure manter esta hierarquia o menos profunda possível. O layout será carregado mais rápido se tiver menos layouts aninhados. Uma hierarquia de visualização grande é melhor do que uma hierarquia de visualização profunda.
Layout linear

É um layout que organiza os filhos em uma única linha horizontal ou vertical. Ele criará uma barra de rolagem se o comprimento da janela exceder o comprimento da tela.
Layout relativo

Permite especificar a localização de objetos filhos relativos entre si (filho A à esquerda do filho B) ou relativos aos pais (alinhados na parte superior do pai).
Criação de layouts com um adaptador
Quando o conteúdo do layout é dinâmico ou não predeterminado, é possível usar um layout que
torne AdapterView
uma subclasse para preencher o layout com visualizações no momento da execução. Uma
subclasse da classe AdapterView
usa um Adapter
para
agrupar dados ao layout. O Adapter
se comporta como um intermediário entre a fonte
dos dados e o layout do AdapterView
, o Adapter
recupera os dados (de uma fonte como uma matriz ou uma consulta de banco de dados) e converte cada entrada
em uma visualização que pode ser adicionada ao layout do AdapterView
.
Alguns layouts comuns retornados por um adaptador:
Preenchimento da visualização de adaptador com dados
É possível preencher um AdapterView
como ListView
ou
GridView
vinculando a instância de AdapterView
a um
Adapter
, que recupera dados de uma fonte externa e cria um View
que representa cada entrada de dados.
O Android oferece diversas subclasses de Adapter
que são úteis para
recuperar diferentes tipos de dados e criar visualizações de um AdapterView
. Os
dois adaptadores mais comuns são:
ArrayAdapter
- Use esse adaptador quando a fonte de dados for uma matriz. Por padrão,
ArrayAdapter
cria uma visualização para cada item de matriz chamandotoString()
em cada item e posicionando o conteúdo em umTextView
.Por exemplo, se você tiver uma matriz de strings que quer exibir em um
ListView
, inicialize um novoArrayAdapter
usando um construtor para especificar o layout de cada string e a matriz de strings:Kotlin
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)
Java
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
Os argumentos desse construtor são:
- Seu aplicativo
Context
- O layout que contém um
TextView
para cada string na matriz - A matriz de strings
Em seguida, simplesmente chame
setAdapter()
emListView
:Kotlin
val listView: ListView = findViewById(R.id.listview) listView.adapter = adapter
Java
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
Para personalizar a aparência de cada item, é possível substituir o método
toString()
para os objetos na matriz. Ou, para criar uma visualização para cada item diferente de umTextView
(por exemplo, se você quiser umImageView
para cada item da matriz), estenda a classeArrayAdapter
e substituagetView()
para retornar o tipo de visualização que quer para cada item. - Seu aplicativo
SimpleCursorAdapter
- Use esse adaptador quando os dados vierem de um
Cursor
. Ao usarSimpleCursorAdapter
, é necessário especificar um layout a usar para cada linha noCursor
e quais colunas noCursor
precisam ser inseridas em determinadas visualizações do layout. Por exemplo, se quiser criar uma lista de nome e número de telefone de pessoas, poderá executar uma consulta que retorna umCursor
que contém uma linha para cada pessoa e colunas para os nomes e números. Depois, crie uma matriz de strings que especifique quais colunas doCursor
estarão no layout para cada resultado e uma matriz de números inteiros especificando as visualizações correspondentes em que cada coluna deve ser colocada:Kotlin
val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER) val toViews = intArrayOf(R.id.display_name, R.id.phone_number)
Java
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};
Ao instanciar o
SimpleCursorAdapter
, passe o layout a usar para cada resultado, oCursor
contendo os resultados e estas duas matrizes:Kotlin
val adapter = SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0) val listView = getListView() listView.adapter = adapter
Java
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
Em seguida, o
.SimpleCursorAdapter
cria uma visualização de cada linha noCursor
usando o layout fornecido por meio da inserção de cada item defromColumns
na visualizaçãotoViews
correspondente.
Se, durante o curso de vida do aplicativo, você mudar os dados subjacentes lidos pelo
adaptador, chame notifyDataSetChanged()
. Isso
notificará a visualização anexada de que os dados foram mudados e que ela precisa ser atualizada.
Processamento de eventos de clique
Para responder a eventos de clique em cada item em um AdapterView
,
implemente a interface AdapterView.OnItemClickListener
. Exemplo:
Kotlin
listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> // Do something in response to the click }
Java
// Create a message handling object as an anonymous class. private OnItemClickListener messageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click } }; listView.setOnItemClickListener(messageClickedHandler);
Outros recursos
Os layouts são usados no app de demonstração Sunflower.