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


75

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

我四处搜寻,但没有找到任何能真正解释Android LintEclipse提示为何建议使用替换掉部分layout_heightlayout_width值的东西0dp

例如,我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或layouth_width的诀窍是什么?

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

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

当一个LinearLayout垂直的,那么layout_weight将影响身高的孩子的ViewS( ListView)。将设置layout_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像我上面使用的那样使用,将导致所有childView都被测量,这将导致更多的CPU时间。此测量将导致您getView(...)被呼叫。我现在已经对此进行了测试,并且getView(...)被调用的次数大大减少了。

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

将其更改为建议的0dpgetView(...)每行仅调用一次。这是一个很大的改进,但是与避免wrap_content使用aListView相比,它有更多的作用0dp

但是,因此的建议0dp确实可以显着提高性能。



1
很高兴找到,我没有找到那个。未接受的答案是对此做出解释的答案
Kirk 2012年

看到这个问题获得的票数超过了最高答案,这让我激动不已,但现在我明白了为什么。很棒的问答。如果您愿意,这将成为一个出色的社区Wiki。谢谢你!
RileyE

Answers:


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提示建议将某些layout_height和layout_width值替换为0dp的内容。

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


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,这样视图的高度或宽度就不会做额外的计算(然后会被忽略)。这个小技巧可以节省CPU周期。

来自:

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


5

据我所知,使用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>

然后尝试将0px替换为match_parent。您会看到结果非常不同。

通常,为了更好的理解和更好的性能,您可能希望使用0px。


3

LinearLayout根据layout_width/layout_height值测量所有子项,然后根据值除以剩余空间(可能为负)layout_weight

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

因此,效率来自于不对孩子进行测量。0dp应该是完全一样有效(和产生完全相同的结果)作为match_parent,或42px,或任何其它固定数目。


1

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

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

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

使用android:layout_height =“ wrap_content”可解决此问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.