Comment obtenir RelativeLayout travailler avec fusion et inclure?
-
22-09-2019 - |
Question
J'ai essayé pendant quelques jours maintenant de faire mes mises en page plus efficace en convertissant d'utiliser plusieurs niveaux de LinearLayouts
imbriqué à un RelativeLayout
et ont rencontré quelques problèmes que je havre de paix pas été en mesure de trouver une solution pour .. .
J'ai cherché le groupe Android débutants et ce site et n'ont pas été en mesure de trouver quelque chose qui me aider à résoudre le problème.
Je lis sur un des blogs que vous pouvez combiner avec mises en page et inclure des balises de fusion. Donc ce que j'ai est un fichier de mise en page principale avec un élément racine RelativeLayout
. A l'intérieur de ce que j'ai 5 inclure des balises qui font référence à 5 différents fichiers de mise en page XML qui ont chacun un élément de fusion pour la racine (tous mes fichiers de fusion sont les mêmes, sauf pour les ids en eux).
Je suis en cours d'exécution en deux problèmes, que je vous expliquerai après la publication d'une version simplifiée de mon code de mise en page:
Fichier de mise en page principale Exemple:
<?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>
Exemple inclus fichier de fusion:
<?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>
Je suis en cours d'exécution en deux problèmes:
1) Les attributs android:layout_*
semblent être ignorés lorsqu'ils sont utilisés dans la balise include et toutes les dispositions fusionnées sont affichées au-dessus de l'autre. Selon ce poste ( http://developer.android.com/resources/ articles / mise en page-tours-reuse.html ) "tout attribut android:layout_*
peut être utilisé avec la balise <include />
"
2) Étant donné que je ne pouvais pas obtenir ce travail j'ai décidé d'essayer d'ajouter un attribut android:layout_below
au premier élément de TextView
dans chaque fusion fichier de mise en page, ce qui signifie que chaque merge fichier serait référence à un identifiant d'un autre fichier de mise en page de fusion ... pour la plupart ce travail réellement effectuées et ma mise en page semble bien. Cependant, je reçois une erreur sur l'un des attributs android:layout_below
en disant qu'il ne peut pas trouver l'id que je ... J'ai spécifié double et triple vérifié les ids pour vous assurer qu'ils étaient corrects. La partie la plus étrange est que j'utilisé la fonction AutoFill
pour mettre l'ID dans l'attribut en premier lieu.
Si quelqu'un a des suggestions ou des solutions de contournement, je serai plus qu'heureux de les essayer. Aussi, si quelqu'un peut penser à une façon pour moi d'avoir un seul fichier fusion de mise en page XML au lieu de 5 qui serait grandement appréciée. Je ne pouvais pas trouver un moyen de le faire parce que je dois avoir accès à chaque élément dans les fichiers de mise en page de fusion lors de l'exécution ...
La solution
Il y a un problème avec la balise include. Vérifier: https://issuetracker.google.com/issues/36908001
Pour résoudre ce problème, assurez-vous écrasez DEUX layout_width
et layout_height
en incluant, sinon tout sera ignoré.
Autres conseils
Voir la réponse plus fortement voté ci-dessous. Le mien est malheureusement pas à jour
je peux aborder une question Justin élevé: incapacité de RelativeLayout à gérer le positionnement d'un inclure (au moins dans ce cas simple, sur un émulateur 1.6)
CommonsWare suggère enroulant le comprend dans un conteneur unique parent, mais le fait afin d'aider les aborder et la portée vues portant le même nom dans les Justin comprend
chacun devrait avoir un conteneur parent unique, et vous le feriez appeler findViewById () sur ce récipient (ViewGroup) plutôt que sur la Activité.
En fait, vous aussi doit le faire afin d'obtenir RelativeLayout se comporter comme prévu:
Cela fonctionne ( pied de page est bien positionné):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<include android:id="@+id/header" layout="@layout/header"
android:layout_alignParentTop="true" />
<WebView android:id="@+id/webView" android:layout_below="@id/header"
android:background="#77CC0000" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:focusable="false" />
<LinearLayout android:layout_alignParentBottom="true"
android:layout_height="wrap_content" android:layout_width="fill_parent">
<include android:id="@+id/footer" layout="@layout/footer" />
</LinearLayout>
</RelativeLayout>
Cela ne ( footer est flottant en haut de l'écran):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<include android:id="@+id/header" layout="@layout/header"
android:layout_alignParentTop="true" />
<WebView android:id="@+id/webView" android:layout_below="@id/header"
android:background="#77CC0000" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:focusable="false" />
<include android:id="@+id/footer" layout="@layout/footer"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Le nu footer inclure ne seront pas alignés en bas de parent, sans LinearLayout environs .. Je ne qualifierais pas ce comportement attendu.
En outre, le WebView semble se fixer bien au en-tête par ID, mais je crois que cela est illusion, en raison de couler simplement ci-dessous l'en-tête verticalement. J'ai aussi essayé de mettre un bouton juste au-dessus du pied de page incluent, mais il eu tout vaporeux et le mal, trop
RelativeLayout avait plus de problèmes à 1,5, mais je l'aime toujours:)
L'homme, c'est vieux, mais il semble arriver au sommet des recherches, donc je vais commenter.
Je pense que l'affaire est que la balise <merge>
combinée avec l'étiquette de <include>
éliminer essentiellement toute sorte de groupe de vues « parent » à ce niveau. Alors, qui êtes-vous exactement demande de « layout_below » quelqu'un d'autre? Personne. Il n'y a pas de vue à ce niveau.
La balise <merge>
prend les vues de l'enfant et les affiche directement dans le parent de la balise <include>
. Il faut donc demander aux enfants dans la mise en page vous y compris pour s'ancrer en conséquence.
Pour le positionnement de travailler sur RelativeLayout vous devez définir les paramètres layout_ de * dans le fichier inclus, pas dans le fichier de mise en page principale. De cette façon,
main_layout.xml
<RelativeLayout
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
....
</RelativeLayout>
<RelativeLayout
android:id="@+id/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
.....
</RelativeLayout>
<include layout="@layout/content_layout" />
content_layout.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/footer"
android:layout_below="@id/header" >
....
</RelativeLayout>
</merge>
Ceci est évidemment pas ce que nous voulons les développeurs, mais il est la seule solution que j'ai trouvé pour éviter la duplication xml
L'androïde: layout_ attributs * semblent être ignoré lorsqu'il est utilisé dans include étiquette et toutes les dispositions sont fusionnées affiché au-dessus de l'autre.
Je suppose que vous ne pouvez pas faire référence, des règles de mise en page, les attributs de android:id
qui sont définis sur des éléments de <include>
, seuls ceux qui sont sur les widgets « vrais » et les conteneurs.
En outre, si quelqu'un peut penser à une façon de moi d'avoir juste une fusion mise en page XML fichier au lieu de 5 qui serait très apprécié.
Simple:. Les mettre tous dans un seul fichier
Je ne pouvais pas trouver un moyen de le faire parce que je dois avoir accès à chaque élément dans les fichiers de mise en page de fusion à exécution
Si vous avez un élément de <include>
ou 1000, tout le contenu doit être accessible à l'exécution. Une exception est si vous avez dupliqué android:id
attributs -. Vous devez bien votre portée findViewById()
appels pour obtenir le bon, comme vous devez lors de l'obtention des widgets à partir d'une ligne de ListView
Si vous pouvez créer un exemple de projet qui utilise 2+ fusionner des fichiers où vous pouvez démontrer que le contenu est pas accessible à l'exécution, laissez-moi savoir.
Dans mon cas, la mise en page que je tentais d'inclure commence par tag <merge
. Quand je l'ai changé à une mise en page, par exemple <RelativeLayout
cela a fonctionné. Ci-dessous l'illustration.
TRAVAIL
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:showIn="@layout/activity_home">
PAS DE TRAVAIL
<merge xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:showIn="@layout/activity_home">
J'ai eu le même problème et même définir layout_width
et layout_height
cela ne fonctionnait pas.
Le problème est que la mise en page que j'incluais avait des étiquettes et après les enlever, tout a fonctionné comme un charme.
Je suppose que la fusion n'est pas une étiquette de mise en page et à cause de cela, il ne peut pas recevoir des paramètres de positionnement et de taille. Étant donné que tout ce que vous définissez dans est transféré à la mise en page de parent intérieur, les paramètres étaient tout simplement jeter.
TL: DR. Il suffit de supprimer les balises, déplacer les définitions xmlns à une véritable mise en page viewholder et vous devriez être bon
Avant:
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<...ui.component.BorderCardView
android:layout_width="112dp"
android:layout_height="32dp"
app:cardCornerRadius="4dp"
app:cardUseCompatPadding="true">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_logout"
android:tint="@color/divider" />
</...ui.component.BorderCardView>
</merge>
Travail:
<...ui.component.BorderCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="112dp"
android:layout_height="32dp"
app:cardCornerRadius="4dp"
app:cardUseCompatPadding="true">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_logout"
android:tint="@color/divider" />
</...ui.component.BorderCardView>