J'ai écrit quelques fichiers de mise en page où j'ai utilisé le layout_weight
attribut pour créer un rapport entre différentes vues.
À un moment donné, je commence à recevoir des avertissements contre les peluches concernant les poids imbriqués.
Je me demande donc pourquoi les poids imbriqués sont mauvais pour la performance et s'il existe un moyen plus efficace de créer un rapport constant entre les dimensions de la vue pouvant être utilisé pour différentes tailles d'écran sans qu'il soit nécessaire de spécifier beaucoup de valeurs de dimensions en dpi à travers plusieurs fichiers de mise en page (pour différentes tailles d’écran, je veux dire).
Je vous remercie!
Les poids imbriqués sont mauvais pour la performance car:
Les poids de mise en page nécessitent qu'un widget soit mesuré deux fois. Lorsqu'un LinearLayout avec des poids non nuls est imbriqué dans un autre LinearLayout avec des poids non nuls, le nombre de mesures augmente de façon exponentielle.
Il vaut mieux utiliser RelativeLayout s et ajuster votre vue en fonction de l'emplacement des autres vues sans utiliser de valeurs de dpi spécifiques.
Mise à jour: Comme nous le savons, la bibliothèque de support en pourcentage est obsolète à partir du niveau 26 de l'API. ConstraintLayout
est le nouveau moyen d'obtenir le même code xml à plat. structure.
Exemples mis à jour:
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/fifty_thirty"
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:background="#ffff8800"
Android:gravity="center"
Android:text="@string/fifty_fifty_text"
Android:textColor="@Android:color/white"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
Android:textSize="25sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
<TextView
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:background="#ffff5566"
Android:gravity="center"
Android:text="@string/fifty_fifty_text"
Android:textColor="@Android:color/white"
Android:textSize="25sp"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintLeft_toRightOf="@id/fifty_thirty"
app:layout_constraintTop_toBottomOf="@id/fifty_thirty"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
</Android.support.constraint.ConstraintLayout>
Mise à jour: Bonne nouvelle Android La bibliothèque de support résout notre problème de performances et de poids imbriqué en désordre LinearLayout
compile 'com.Android.support:percent:23.0.0'
Considérez cette disposition simple pour démontrer la même chose.
<Android.support.percent.PercentRelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/fifty_huntv"
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:background="#ff7acfff"
Android:text="20% - 50%"
Android:textColor="@Android:color/white"
app:layout_heightPercent="20%"
app:layout_widthPercent="50%" />
<TextView
Android:layout_width="0dp"
Android:layout_height="0dp"
Android:layout_toRightOf="@id/fifty_huntv"
Android:background="#ffff5566"
Android:text="80%-50%"
app:layout_heightPercent="80%"
app:layout_widthPercent="50%"
/>
</Android.support.percent.PercentRelativeLayout>
Dégradé de la performance évitée imbriquée LinearLayout
avec des poids. Vraiment génial !!!.
Je pense (et je vais probablement être enflammé pour cela), mais encore une fois, je pense que mon téléphone a un processeur quad core pour rivaliser (sinon complètement détruire) la plupart des ordinateurs personnels domestiques.
Je pense aussi que ce type de capacité matérielle est l'avenir des téléphones.
J'arrive donc à la conclusion que tant que vous ne vous ennuyez pas avec l'imbrication (dans MHO, une disposition ne doit jamais être supérieure à 4 niveaux, et si c'est le cas, vous vous trompez probablement), votre téléphone s'en fiche d'avoir des poids.
Il y a beaucoup de choses que vous pouvez faire qui auront un effet beaucoup plus profond sur les performances, alors que vous vous inquiétez du temps que votre processeur fasse des calculs supplémentaires.
(Veuillez noter que je suis un peu humoristique et que je ne prends donc pas trop au sérieux ce billet. Autrement, il faut d'abord optimiser les choses, et s'inquiéter d'un poids de 2 ou 3 kilos n'est pas utile. votre santé)
La principale raison pour laquelle les poids imbriqués sont incorrects est que, lorsqu'un modèle a des enfants avec un poids, il doit être mesuré deux fois (je pense que cela est mentionné dans l'avertissement de peluches). Cela signifie qu'une disposition pondérée qui contient également une disposition pondérée doit être mesurée quatre fois, et chaque "couche" de poids que vous ajoutez augmente les mesures avec une puissance de deux.
Dans ICS (niveau 14 de l'API), le GridLayout
a été ajouté, ce qui permet d'offrir des solutions simples et "plates" pour de nombreuses dispositions qui nécessitaient auparavant une pondération. vous développez pour des versions antérieures de Android vous aurez un peu plus de mal à enlever les poids, mais vous utiliserez un RelativeLayout
et vous ferez disparaître le plus possible de votre mise en page dans cette cabine. beaucoup de poids imbriqués.
Il existe une solution simple pour éviter les LinearLayouts imbriqués avec des poids - utilisez simplement Tablelayout avec weightSum et LinearLayout imbriqué avec weightSum - Tablelayout a les mêmes attributs que LinearLayout (orientation, weightSum, layout_weight, etc.) et ne affiche pas le message - "nested weights mauvais pour la performance "
Exemple:
<TableLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
Android:weightSum="1">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="0.8"/>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="0.2"
Android:orientation="horizontal"
Android:weightSum="1">
<ImageView
Android:layout_height="match_parent"
Android:layout_width="0dp"
Android:layout_weight="0.4"/>
<TextView
Android:layout_height="match_parent"
Android:layout_width="0dp"
Android:layout_weight="0.6"/>
</LinearLayout>
</TableLayout>
Je pense que la seule alternative est de créer une fonction qui s'appellerait onResume et définira toutes les tailles et positions. Quoi qu'il en soit, en poids, vous pouvez définir uniquement les tailles mais pas de rembourrage (donc les mises en page deviennent encore plus compliquées), pas de textSize (impossible de compenser cela d'une manière ou d'une autre), encore moins le nombre de lignes.