76

已填写此问题末尾的答案,结合评论和解决方案。

问题

我四处搜索,但没有找到任何真正解释为什么Android Lint以及一些Eclipse提示建议用.layout_heightlayout_width0dp

例如,我有一个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 item进行更改。这些在更改前后看起来都一样,但我有兴趣了解为什么这些是性能提升器。

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

当 aLinearLayout垂直时,layout_weight将影响孩子s ( )的高度。设置为将导致该属性被忽略。ViewListViewlayout_height0dp

例子

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

当 aLinearLayout水平时,layout_weight将影响子s ( )的宽度。设置为将导致该属性被忽略。ViewListViewlayout_width0dp

例子

<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的那样使用会导致测量所有 child View,这将导致更多的 CPU 时间。此测量将导致您getView(...)被调用。我现在已经对此进行了测试,并且getView(...)调用的次数大大减少了。

当我wrap_content在两个ListViews上使用时getView(...),每行调用 3 次,每行调用ListView4 次。

将此更改为推荐的0dpgetView(...)每行仅调用一次。这是一个相当大的改进,但更多的是避免wrap_content使用 aListView而不是0dp.

但是,0dp由于这个原因,建议确实大大提高了性能。

4

5 回答 5

24

首先你有这个,

<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

此外,

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

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

于 2012-08-18T07:53:19.413 回答
12

所以当在 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。没关系。但建议使用 0dp,因此 View 不会对其高度或宽度进行额外计算(然后将其忽略)。这个小技巧只是节省了 CPU 周期。

从 :

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

于 2012-08-18T07:50:17.407 回答
6

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

这取决于您使用的重量。如果只使用 weight 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。

于 2012-08-18T08:40:59.623 回答
3

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

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

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

于 2014-03-20T06:40:53.063 回答
1

谨慎使用 android:layout_height="0dp"

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

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

使用 android:layout_height="wrap_content" 解决了这个问题

于 2014-04-15T14:01:27.237 回答