android - studio - ¿Por qué se considera 0dp una mejora del rendimiento?
que es android studio (5)
Se completó una respuesta al final de esta pregunta, que combina comentarios y soluciones.
Pregunta
Busqué pero no encontré nada que realmente explique por qué Android Lint , así como algunas sugerencias de Eclipse sugieren reemplazar algunos valores de layout_height
y layout_width
con 0dp
.
Por ejemplo, tengo un ListView
que se sugirió para ser cambiado
antes de
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
Después
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
Del mismo modo, sugirió cambios a un elemento ListView . Todos estos tienen el mismo aspecto antes y después de los cambios, pero estoy interesado en comprender por qué estos son potenciadores del rendimiento.
Alguien tiene una explicación de por qué? Si ayuda, aquí está el diseño general con 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>
Responder
Aquí presento una respuesta porque en realidad es una combinación de respuestas y enlaces a los que se hace referencia a continuación. Si estoy equivocado en algo, házmelo saber.
De ¿Cuál es el truco con 0dip layout_height o layouth_width?
Hay 3 atributos generales de diseño que funcionan con ancho y alto
-
android:layout_height
-
android:layout_width
-
android:layout_weight
Cuando un LinearLayout
es vertical , el layout_weight
afectará la altura de la View
niño s ( ListView
). Establecer el layout_height
en 0dp
causará que este atributo sea ignorado.
Ejemplo
<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>
Cuando un LinearLayout
es horizontal , el layout_weight
afectará el ancho de la View
niño s ( ListView
). Establecer el layout_width
en 0dp
causará que este atributo sea ignorado.
Ejemplo
<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 razón para querer ignorar el atributo es que, si no lo ignora, se usaría para calcular el diseño que utiliza más tiempo de CPU.
Además, esto evita cualquier confusión sobre cómo debería verse el diseño cuando se usa una combinación de los tres atributos. Esto es resaltado por @android developer en una respuesta a continuación.
Además, Android Lint y Eclipse dicen usar 0dip
. A partir de esa respuesta a continuación, puede usar 0dip
, 0dp
, 0px
, etc. ya que un tamaño cero es el mismo en cualquiera de las unidades.
Evite wrap_content en ListView
Desde Layout_width de ListView
Si alguna vez se ha preguntado por qué getView(...)
se llama tantas veces como yo, se relaciona con wrap_content
.
El uso de wrap_content
como lo estaba utilizando anteriormente hará que se midan todas las View
secundarias, lo que provocará un mayor tiempo de CPU. Esta medida hará que se getView(...)
su getView(...)
. Ahora lo he probado y la cantidad de veces que se getView(...)
se reduce drásticamente.
Cuando estaba usando wrap_content
en dos ListView
, se getView(...)
3 veces para cada fila en un ListView
y 4 veces para cada fila en el otro.
Cambiando esto al 0dp
recomendado, getView(...)
fue llamado solo una vez por cada fila. Esta es una gran mejora, pero tiene más que ver con evitar wrap_content
en un ListView
que en el 0dp
.
Sin embargo, la sugerencia de 0dp
mejora sustancialmente el rendimiento debido a esto.
Antes que nada tienes esto,
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
Nunca tome la altura de ListView como wrap_content, que dará lugar a problemas. Here
está la razón para eso y this answer
.
Además,
Busqué por todos lados pero no he encontrado nada que realmente explique por qué Android Lint, así como algunas sugerencias de Eclipse, sugieren reemplazar algunos valores de layout_height y layout_width por 0dp.
Es porque estás usando layout_weight = "1"
que significa que tu ListView toma la altura que está disponible para él. Entonces, en ese caso no hay necesidad de usar layout_height = "wrap_content"
simplemente cámbielo a android:layout_height="0dp"
y la altura de ListView será administrada por layout_weight = "1"
.
Entonces, cuando android: layout_weight se usa en View X y LinearLayout es horizontal, entonces X''s android: layout_width simplemente se ignora.
Similar, cuando android: layout_weight se usa en View X y LinearLayout es vertical, entonces X''s android: layout_height se ignora.
Esto realmente significa que puede poner cualquier cosa en esos campos ignorados: 0dp o fill_parent o wrap_content. No importa. Pero se recomienda utilizar 0dp para que View no haga un cálculo adicional de su altura o ancho (que luego se ignora). Este pequeño truco simplemente ahorra ciclos de CPU.
de :
Hasta donde yo sé, hay una diferencia entre usar 0dp (o 0px por cierto, es lo mismo ya que 0 es 0 sin importar cuál es la unidad aquí) y el wrap_content o fill_parent (o match_parent, es el mismo).
depende del peso que uses si solo usa el peso de 1, todos tienen el mismo aspecto, pero el significado siempre es diferente y es importante para el rendimiento.
para mostrar esto, intente lo siguiente:
<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>
y luego intente reemplazar el 0px con match_parent. verás que el resultado es muy diferente.
generalmente, para una mejor comprensión y un mejor rendimiento, querrá usar 0px.
Precaución al usar android: layout_height = "0dp"
Lo he encontrado en un ListView (con el reciclaje de vistas recomendado usando convertView, véase, por ejemplo, http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ ), estableciendo android: layout_height = " 0dp "para la fila TextView puede conducir al truncamiento de texto para el contenido de texto de varias líneas.
Cada vez que un objeto TextView que se utilizó anteriormente para mostrar un texto que se ajusta en una sola línea se recicla para mostrar un texto más largo que necesita más de una línea, ese texto se trunca en una sola línea.
El problema se soluciona usando android: layout_height = "wrap_content"
LinearLayout
mide todos los hijos de acuerdo con los valores de layout_width
/ layout_height
, luego divide el espacio sobrante (que puede ser negativo) según los valores de layout_weight
.
0dp
es más eficiente que wrap_content
en este caso porque es más eficiente simplemente usar cero para la altura original y luego dividir la altura completa de los padres en base al peso que medir primero al niño y luego dividir el resto en función del peso.
Entonces, la eficiencia proviene de no medir al niño. 0dp
debe ser exactamente igual de eficiente (y producir exactamente el mismo resultado) que match_parent
, o 42px
, o cualquier otro número fijo.