为什么0dp被认为是性能增强



本问题末尾的答案已填写完毕,结合备注和解决方案。

问题

我四处搜索,但没有找到任何真正解释为什么Android Lint以及一些Eclipse提示建议用0dp替换一些layout_heightlayout_width值的东西。

例如,我有一个建议更改的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>

类似地,它建议对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或layout_width的诀窍是什么?

有3个通用布局属性适用于宽度高度

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

LinearLayout垂直时,layout_weight将影响子Views(ListView)的高度。将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将影响子Views(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时间的布局。

此外,当使用这三个属性的组合时,这可以防止对布局应该是什么样子的任何混淆。@androiddeveloper在下面的回答中强调了这一点。

此外,Android LintEclipse都表示使用0dip。根据下面的答案,您可以使用0dip0dp0px等,因为零大小在任何单位中都是相同的。

避免ListView上的wrap_content

从ListView 的Layout_width

如果你曾经想知道为什么getView(...)会像我一样被调用这么多次,那么事实证明它与wrap_content有关。

像我上面使用的那样使用wrap_content将导致测量所有子View,这将导致更多的CPU时间。此测量将导致调用您的getView(...)。我现在已经测试过了,调用getView(...)的次数大大减少了。

当我在两个ListView上使用wrap_content时,一个ListView上的每行调用getView(...) 3次,另一个上的每行都调用4次。

将其更改为推荐的0dp,每行仅调用getView(...)一次。这是一个相当大的改进,但更多的是在ListView上避免wrap_content,而不是在0dp上。

然而,CCD_ 40的建议确实因此而显著提高了性能。

首先,

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

永远不要将ListView的高度视为wrap_content,这会导致麻烦。CCD_ 41和CCD_。

此外,

我四处寻找,但没有找到任何真正解释原因的东西Android Lint和一些Eclipse提示建议替换一些layout_height和layout_width值的0dp。

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

因此,当在视图X上使用android:layout_weight并且LinearLayout是水平的时,X的android:layout_width将被忽略。

类似地,当在视图X上使用android:layout_weight并且LinearLayout是垂直的时,X的android:layout_height将被忽略。

这实际上意味着,您可以在那些被忽略的字段中放入任何内容:0dp、fill_present或wrap_content。没关系。但建议使用0dp,这样视图就不会对其高度或宽度进行额外计算(然后会被忽略)。这个小技巧简单地节省了CPU周期。

来自:

0dip layout_height或layout_width的诀窍是什么?

据我所知,使用0dp(或0px-btw,这是一样的,因为无论这里的单位是什么,0都是0)和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_parent替换0px。你会发现结果大不相同。

通常,为了更好地理解和提高性能,您会希望使用0px。

LinearLayout根据layout_width/layout_height的值测量所有子项,然后根据layout_weight的值划分剩余空间(可能为负数)。

在这种情况下,0dpwrap_content更有效,因为只对原始身高使用零,然后根据体重分割父母的全身高比先测量孩子,然后根据重量分割剩余部分更有效。

因此,效率来自于不测量孩子。0dp应该与match_parent42px或任何其他固定数一样有效(并产生完全相同的结果)。

重新使用android时的注意事项:layout_height="0dp"

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

每当以前用于显示适合单行的文本的TextView对象被回收以显示需要多行的较长文本时,该文本就会被截断为单行。

使用android:layout_height="wrap_content"

解决了这个问题

最新更新