Estou tentando há alguns dias tornar meus layouts mais eficientes, convertendo o uso de vários níveis de aninhados LinearLayouts
em um RelativeLayout
e encontrei alguns problemas para os quais não consegui encontrar uma solução alternativa ...
Eu pesquisei o grupo de iniciantes em Android e este site e não consegui encontrar nada que pudesse me ajudar a resolver o problema.
Eu li em um dos blogs que você pode combinar layouts com mesclar e incluir tags. Portanto, o que tenho é um arquivo de layout principal com um RelativeLayout
elemento raiz. Dentro disso, tenho 5 tags de inclusão que fazem referência a 5 arquivos de layout xml diferentes, cada um com um elemento de mesclagem para a raiz (todos os meus arquivos de mesclagem são iguais, exceto pelos ids neles).
Estou tendo dois problemas, que explicarei depois de postar uma versão simplificada do meu código de layout:
Arquivo de layout principal de amostra:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/translucent_gray" >
<include
android:id="@+id/running_gallery_layout_id"
layout="@layout/running_gallery_layout" />
<include
android:id="@+id/recent_gallery_layout_id"
layout="@layout/recent_gallery_layout"
android:layout_below="@id/running_gallery_layout_id" />
<include
android:id="@+id/service_gallery_layout_id"
layout="@layout/service_gallery_layout"
android:layout_below="@id/recent_gallery_layout_id" />
<include
android:id="@+id/process_gallery_layout_id"
layout="@layout/process_gallery_layout"
android:layout_below="@id/service_gallery_layout_id" />
</RelativeLayout>
Arquivo de mesclagem incluído:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
style="@style/TitleText"
android:id="@+id/service_gallery_title_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:text="@string/service_title" />
<Gallery
android:id="@+id/service_gallery_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_below="@id/service_gallery_title_text_id" />
<TextView
style="@style/SubTitleText"
android:id="@+id/service_gallery_current_text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/service_gallery_title_text_id"
android:layout_above="@id/service_gallery_id" />
</merge>
Estou tendo dois problemas:
1) Os android:layout_*
atributos parecem ser ignorados quando usados na tag de inclusão e todos os layouts mesclados são exibidos uns sobre os outros. De acordo com esta postagem ( http://developer.android.com/resources/articles/layout-tricks-reuse.html ) "qualquer android:layout_*
atributo pode ser usado com a <include />
tag"
2) Como não consegui fazer isso funcionar, decidi tentar adicionar um android:layout_below
atributo ao primeiro TextView
item em cada arquivo de layout de mesclagem, o que significa que cada arquivo de mesclagem faria referência a um id de outro arquivo de layout de mesclagem ... Na maioria das vezes isso realmente funcionou e meu layout parece bom. No entanto, recebo um erro em um dos android:layout_below
atributos dizendo que ele não consegue encontrar o id que eu especifiquei ... Verifiquei duas ou três vezes os ids para ter certeza de que estavam corretos. A parte mais estranha é que usei o AutoFill
recurso para colocar o id no atributo em primeiro lugar.
Se alguém tiver alguma sugestão ou solução alternativa, terei todo o gosto em experimentá-los. Além disso, se alguém puder pensar em uma maneira de eu ter apenas um arquivo de layout xml mesclado em vez de 5, isso seria muito apreciado. Não consegui encontrar uma maneira de fazer isso porque preciso ter acesso a cada item nos arquivos de layout de mesclagem em tempo de execução ...
layout_width
elayout_height
estabeleci meu<include>
. Eu tentei também definirlayout_width
elayout_height
no meu<merge>
mas sem sucesso. O que estou perdendo ?Veja a resposta mais votada abaixo. O meu está terrivelmente desatualizado
Posso resolver um problema que Justin levantou: incapacidade do RelativeLayout de gerenciar o posicionamento de um include (pelo menos neste caso simples, em um emulador 1.6)
CommonsWare sugere envolver os includes em um único container pai, mas faz isso para ajudar a endereçar e definir o escopo de Views com nomes idênticos dentro dos includes de Justin
Na verdade, você também deve fazer isso para que o RelativeLayout se comporte conforme o esperado:
Isso funciona (o rodapé está bem posicionado):
Isso não acontece (o rodapé está flutuando no topo da tela):
O include de rodapé descalço não se alinhará à parte inferior do pai, sem o LinearLayout circundante. Eu não chamaria esse comportamento esperado.
Além disso, o WebView parece se anexar bem ao cabeçalho por ID, mas acredito que isso seja uma ilusão, porque simplesmente flui abaixo do cabeçalho verticalmente. Eu também tentei definir um botão logo acima do footer include, mas ficou todo flutuante e errado também
RelativeLayout teve mais problemas no 1.5, mas eu ainda gosto :)
fonte
Cara, isso é antigo, mas parece que aparece no topo das pesquisas, então vou comentar.
Acho que o truque aqui é que a
<merge>
tag combinada com a<include>
tag remove essencialmente qualquer tipo de grupo de visualização "pai" nesse nível. Então, quem exatamente você está pedindo para "layout_below" outra pessoa? Ninguém. Não há visão nesse nível.A
<merge>
tag pega as visualizações filhas e as coloca diretamente no pai da<include>
tag. Você deve, portanto, pedir aos filhos no layout que está incluindo que se ancorem de acordo.fonte
Para que o posicionamento funcione no RelativeLayout, você precisa definir os parâmetros layout_ * no arquivo de inclusão, não no arquivo de layout principal. Dessa maneira
main_layout.xml
content_layout.xml
Obviamente, isso não é o que nós, desenvolvedores, queremos, mas é a única solução que encontrei para evitar a duplicação de xml
fonte
Meu palpite é que você não pode fazer referência, a partir de regras de layout,
android:id
atributos que são definidos em<include>
elementos, apenas aqueles que estão em widgets e contêineres "reais".Simples: coloque todos em um arquivo.
Quer você tenha um
<include>
elemento ou 1.000, todo o conteúdo deve estar acessível em tempo de execução. Uma exceção é se você tiverandroid:id
atributos duplicados - você precisaria definir o escopo adequado de suasfindViewById()
chamadas para obter o correto, assim como faz ao obter widgets de uma linha ListView.Se você pode criar um projeto de amostra que usa 2+ arquivos de mesclagem onde você pode demonstrar que o conteúdo não está acessível em tempo de execução, me avise.
fonte
experimentar :
fonte
No meu caso, o layout que estava tentando incluir começa com
<merge
tag. Quando mudei para um layout, diga<RelativeLayout
que funcionou. Abaixo está a ilustração.TRABALHANDO
NÃO ESTÁ FUNCIONANDO
fonte
Tive o mesmo problema e até defini
layout_width
elayout_height
não funcionou. O problema era que o layout que eu estava incluindo tinha tags e depois de removê-las, tudo funcionou perfeitamente. Suponho que merge não seja uma tag de layout e por isso não pode receber parâmetros de posicionamento e tamanho. Como tudo que você define é transferido para o layout pai interno, as configurações foram descartadas.TL: DR: Apenas remova as tags, mova as definições xmlns para um visualizador de layout real e você deve estar bem.
Antes:
Trabalhando:
fonte