web-dev-qa-db-fra.com

Pourquoi 0dp est-il considéré comme une amélioration des performances?

Une réponse à la fin de cette question a été remplie, combinant remarques et solutions.

Question

J'ai cherché mais je n'ai rien trouvé qui explique vraiment pourquoi Android Lint ainsi que certains Eclipse des indices suggèrent de remplacer certains layout_height Et layout_width Valeurs avec 0dp.

Par exemple, j'ai un ListView qui a été suggéré de changer

Avant

<ListView
    Android:id="@Android:id/list"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_weight="1">
</ListView>

Après

<ListView
    Android:id="@Android:id/list"
    Android:layout_width="match_parent"
    Android:layout_height="0dp"
    Android:layout_weight="1">
</ListView>

De même, il a suggéré de modifier un élément ListView. Ces éléments se ressemblent tous avant et après les modifications, mais je suis intéressé à comprendre pourquoi ce sont des boosters de performances.

Quelqu'un a une explication de pourquoi? Si cela peut vous aider, voici une présentation générale avec le ListView.

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent">

    <ImageView
        Android:id="@+id/logo_splash"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">
    </ImageView>

    <LinearLayout
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:orientation="vertical"
        Android:background="@color/background"
        Android:layout_below="@id/logo_splash">

        <ListView
            Android:id="@Android:id/list"
            Android:layout_width="match_parent"
            Android:layout_height="0dp"
            Android:layout_weight="1">
        </ListView>

        <TextView
            Android:id="@Android:id/empty"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/no_upcoming" />

    </LinearLayout>        
</RelativeLayout>

Répondre

Je mets une réponse ici parce que c'est vraiment une combinaison de réponses et de liens référencés ci-dessous. Si je me trompe sur quelque chose, faites-le moi savoir.

De Quelle est l'astuce avec 0dip layout_height ou layouth_width?

Il existe 3 attributs de mise en page généraux qui fonctionnent avec largeur et hauteur

  1. Android:layout_height
  2. Android:layout_width
  3. Android:layout_weight

Lorsqu'un LinearLayout est vertical, alors le layout_weight Affectera la hauteur de l'enfant View s (ListView). Si vous définissez layout_height Sur 0dp, Cet attribut sera ignoré.

Exemple

<LinearLayout
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical">
    <ListView
        Android:id="@Android:id/list"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1">
    </ListView>
</LinearLayout>

Lorsqu'un LinearLayout est horizontal, alors le layout_weight Affectera la largeur de l'enfant View s (ListView). Si vous définissez layout_width Sur 0dp, Cet attribut sera ignoré.

Exemple

<LinearLayout
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="horizontal">
    <ListView
        Android:id="@Android:id/list"
        Android:layout_width="0dp"
        Android:layout_height="match_parent"
        Android:layout_weight="1">
    </ListView>
</LinearLayout>

La raison de vouloir ignorer l'attribut est que si vous ne l'ignorez pas, il serait utilisé pour calculer la disposition qui utilise plus de temps CPU.

De plus, cela évite toute confusion quant à l'apparence de la disposition lors de l'utilisation d'une combinaison des trois attributs. Ceci est mis en évidence par @ développeur Android dans une réponse ci-dessous.

En outre, Android Lint et Eclipse disent tous deux d'utiliser 0dip. À partir de cette réponse ci-dessous, vous pouvez utiliser 0dip, 0dp, 0px, Etc. car une taille nulle est la même dans toutes les unités.

Évitez wrap_content sur ListView

De Layout_width d'un ListView

Si vous vous êtes déjà demandé pourquoi getView(...) est appelé autant de fois que moi, cela s'avère être lié à wrap_content.

L'utilisation de wrap_content Comme j'utilisais ci-dessus entraînera la mesure de tous les View enfants, ce qui entraînera un temps processeur supplémentaire. Cette mesure provoquera l'appel de votre getView(...). J'ai maintenant testé cela et le nombre d'appels de getView(...) est considérablement réduit.

Lorsque j'utilisais wrap_content Sur deux ListView s, getView(...) était appelée 3 fois pour chaque ligne sur une ListView et 4 fois pour chaque ligne sur le autre.

En changeant ceci en 0dp Recommandé, getView(...) n'a été appelée qu'une seule fois pour chaque ligne. C'est une amélioration, mais cela a plus à voir avec le fait d'éviter wrap_content Sur un ListView que sur le 0dp.

Cependant, la suggestion de 0dp Améliore considérablement les performances à cause de cela.

72
Kirk

Tout d'abord, vous avez ceci,

<ListView
    Android:id="@Android:id/list"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_weight="1">
</ListView>

Ne prenez jamais la hauteur de ListView comme wrap_content, cela pourrait entraîner des problèmes. Here en est la raison et this answer .

En outre,

J'ai cherché autour de moi, mais je n'ai rien trouvé qui explique vraiment pourquoi Android Lint ainsi que certains indices Eclipse suggèrent de remplacer certaines valeurs de layout_height et layout_width par 0dp.

C'est parce que vous utilisez layout_weight = "1" cela signifie que votre ListView prend autant de hauteur que possible. Donc, dans ce cas, il n'est pas nécessaire d'utiliser layout_height = "wrap_content" il suffit de le changer en Android:layout_height="0dp" et la hauteur de ListView seront gérées par layout_weight = "1".

22
Lalit Poptani

Ainsi, lorsque Android: layout_weight est utilisé sur View X et LinearLayout est horizontal, Android: layout_width de X est simplement ignoré.

De même, lorsque Android: layout_weight est utilisé sur View X et LinearLayout est vertical, Android: layout_height de X est ignoré.

Cela signifie en fait que vous pouvez mettre n'importe quoi dans ces champs ignorés: 0dp ou fill_parent ou wrap_content. Ça n'a pas d'importance. Mais il est recommandé d'utiliser 0dp pour que les View n'effectuent pas de calcul supplémentaire de leur hauteur ou largeur (qui est ensuite ignoré). Cette petite astuce économise simplement les cycles de processeur.

de :

Quelle est l'astuce avec 0dip layout_height ou layouth_width?

12
Archie.bpgc

pour autant que je sache, il y a une différence entre utiliser 0dp (ou 0px btw, c'est la même chose puisque 0 est 0 quelle que soit l'unité ici) et wrap_content ou fill_parent (ou match_parent, c'est la même chose).

cela dépend du poids que vous utilisez. si vous n'utilisez qu'un poids de 1, ils se ressemblent tous, mais la signification est toujours différente et elle est importante pour les performances.

afin de le montrer, essayez ce qui suit:

<LinearLayout 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" Android:orientation="vertical">

  <TextView Android:id="@+id/textView1" Android:layout_width="match_parent"
    Android:layout_height="0px" Android:text="1" Android:background="#ffff0000"
    Android:layout_weight="1" Android:gravity="center"
    Android:textColor="#ffffffff" Android:textSize="20sp" />

  <TextView Android:id="@+id/textView2" Android:layout_width="match_parent"
    Android:layout_height="0px" Android:text="2" Android:background="#ff00ff00"
    Android:layout_weight="2" Android:gravity="center"
    Android:textColor="#ffffffff" Android:textSize="20sp" />

  <TextView Android:id="@+id/textView3" Android:layout_width="match_parent"
    Android:layout_height="0px" Android:text="3" Android:background="#ff0000ff"
    Android:layout_weight="3" Android:gravity="center"
    Android:textColor="#ffffffff" Android:textSize="20sp" />

</LinearLayout>

puis essayez de remplacer le 0px par match_parent. vous verrez que le résultat est très différent.

généralement, pour une meilleure compréhension et de meilleures performances, vous voudrez utiliser 0px.

5
android developer

LinearLayout mesure tous les enfants selon layout_width/layout_height valeurs, puis divise l'espace restant (qui peut être négatif) en fonction de layout_weight valeurs.

0dp est plus efficace que wrap_content dans ce cas, car il est plus efficace d'utiliser simplement zéro pour la taille d'origine, puis de diviser la hauteur totale du parent en fonction du poids que de mesurer l'enfant d'abord, puis de diviser le reste en fonction du poids.

L'efficacité vient donc de ne pas mesurer l'enfant. 0dp devrait être exactement aussi efficace (et produire exactement le même résultat) que match_parent, ou 42px, ou tout autre numéro fixe.

3
Karu

Attention concernant Android: layout_height = "0dp"

J'ai trouvé cela dans un ListView (avec le recyclage recommandé de View en utilisant convertView, voir par exemple http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ ) , la définition d'Android: layout_height = "0dp" pour la ligne TextView peut entraîner la troncature du texte pour le contenu de texte sur plusieurs lignes.

Chaque fois qu'un objet TextView qui était précédemment utilisé pour afficher un texte qui tenait sur une seule ligne est recyclé pour afficher un texte plus long qui a besoin de plus d'une ligne, ce texte est tronqué en une seule ligne.

Le problème est résolu en utilisant Android: layout_height = "wrap_content"

1
Damien