为什么0dp被认为是性能提升?

填补了这个问题的答案 ,结合了言论和解决scheme。

我周围search,但没有发现任何真正解释为什么Android Lint以及一些Eclipse提示build议用0dpreplace一些layout_heightlayout_width值。

例如,我有一个build议改变的ListView

之前

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

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

同样,它build议对ListView项目进行更改。 这些在变化之前和之后都是一样的,但我有兴趣了解为什么这些是性能提升者。

任何人都有解释为什么? 如果有帮助,这里是与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> 

回答

我在这里给出了一个答案,因为它实际上是下面的答案和参考链接的组合。 如果我错了什么,请让我知道。

从0dip layout_height或layouth_width是什么技巧?

有3个一般布局属性与宽度高度一起工作

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

当一个LinearLayout垂直的 ,那么layout_weight将影响子ViewListView )的高度 。 将layout_height设置为0dp将导致该属性被忽略。

 <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> 

当一个LinearLayout水平的 ,那么layout_weight将会影响子View宽度ListView )。 将layout_width设置为0dp将导致该属性被忽略。

 <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> 

要忽略该属性的原因是,如果您不忽略它,它将用于计算使用更多CPU时间的布局。

此外,这可以防止在使用三个属性的组合时布局应该看起来像什么混淆。 @android开发人员在下面的答案中突出显示了这一点。

而且, Android LintEclipse都声称使用0dip 。 从下面的答案,你可以使用0dip0dp0px等,因为零大小是在任何单位相同。

避免ListView上的wrap_content

从ListView的Layout_width

如果你曾经想知道为什么getView(...)像我这样被调用了很多次,结果就和wrap_content有关。

像我上面使用的wrap_content会导致所有的子View被测量,这将导致更多的CPU时间。 这个测量会导致你的getView(...)被调用。 我现在已经testing了这个,调用getView(...)的次数大大减less了。

当我在两个ListView上使用wrap_content时, getView(...)在一个ListView上被调用了3次,而在另一个ListView上被调用了4次。

将其更改为推荐的0dpgetView(...)仅对每行调用一次。 这是一个相当大的改进,但更多的是避免在一个ListView wrap_content0dp

然而,由于这个原因, 0dp的build议大大提高了性能。

首先你有这个,

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

不要把ListView的高度当作wrap_content,这会导致麻烦。 Here是这个和this answer的原因。

此外,

我周围search,但还没有发现任何真正解释为什么Android Lint以及一些Eclipse提示build议用0dpreplace一些layout_height和layout_width值。

因为你正在使用layout_weight = "1" ,这意味着你的ListView的高度尽可能多的可用。 因此,在这种情况下,不需要使用layout_height = "wrap_content"只需将其更改为android:layout_height="0dp" ,ListView的高度将由layout_weight = "1"进行pipe理。

所以当在View X上使用android:layout_weight并且LinearLayout是水平的,那么X的android:layout_width将被忽略。

类似的,当在View X上使用android:layout_weight并且LinearLayout是垂直的,那么X的android:layout_height被忽略。

这实际上意味着,你可以把任何东西放在这些被忽略的字段中:0dp或者fill_parent或者wrap_content。 没关系。 但build议使用0dp,因此视图不会额外计算它们的高度或宽度(然后忽略)。 这个小窍门简单地节省了CPU周期。

来自:

0dip layout_height或layouth_width有什么用?

据我所知,使用0dp(或0px顺便说一句,这是相同的,因为0是0,不pipe这里是什么单位)和wrap_content或fill_parent(或match_parent,它是相同的)之间的区别。

这取决于你使用的重量。 如果只使用1的权重,它们看起来都是一样的,但意义总是不同的,对于性能来说非常重要。

为了显示这一点,请尝试以下操作:

 <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> 

然后尝试用match_parentreplace0px。 你会看到结果是非常不同的。

通常,为了更好的理解和更好的性能,你会想使用0px。

LinearLayout根据layout_width / layout_height值来测量所有的孩子,然后根据layout_height值来分割剩余空间(可能是负数)。

在这种情况下, 0dpwrap_content更高效,因为对原始高度使用零,然后根据权重对父项的完整高度进行分割比先测量子项更高效,然后根据权重对剩余项进行分割。

所以效率来自不衡量孩子。 0dp应该与match_parent42px或任何其他固定数字一样高效(并产生完全相同的结果)。

注意重新使用android:layout_height =“0dp”

我发现,在一个ListView(推荐使用convertView视图回收,请参阅例如http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ ),设置android:layout_height =“ 0dp“行的TextView可能会导致多行文本内容的文本截断。

无论何时以前用于显示装入一行的文本的TextView对象被回收以显示需要多行的较长文本时,该文本将被截断为单行。

该问题是通过使用android:layout_height =“wrap_content”