Android 为什么 0dp 被认为是一种性能增强?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12016781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is 0dp considered a performance enhancement?
提问by Kirk
An answerat the end of this question has been filled out, combining remarks and solutions.
已填写本题末尾的一个答案,结合评论和解决方案。
Question
题
I searched around but haven't found anything that really explains why Android Lintas well as some Eclipsehints suggest replacing some layout_height
and layout_width
values with 0dp
.
我四处搜索,但没有找到任何能真正解释为什么Android Lint以及一些Eclipse提示建议将 somelayout_height
和layout_width
values替换为0dp
.
For example, I have a ListView
that was suggested to be changed
例如,我有一个ListView
建议更改的
Before
前
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
After
后
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
Similarly, it suggested changes to a ListView item. These all look the same before and after the changes, but I'm interested in understanding why these are performance boosters.
同样,它建议更改ListView item。这些在更改前后看起来都一样,但我有兴趣了解为什么这些是性能助推器。
Anyone have an explanation of why? If it helps, here is general layout with the 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>
Answer
回答
I'm putting in an answer here because it's really a combination of answers and referenced links below. If I'm wrong on something, do let me know.
我在这里输入答案是因为它实际上是答案和下面参考链接的组合。如果我做错了什么,请告诉我。
From What is the trick with 0dip layout_height or layouth_width?
从0dip layout_height 或 layouth_width 的技巧是什么?
There are 3 general layout attributes that work with widthand height
有 3 个通用布局属性适用于宽度和高度
android:layout_height
android:layout_width
android:layout_weight
android:layout_height
android:layout_width
android:layout_weight
When a LinearLayout
is vertical, then the layout_weight
will effect the heightof the child View
s (ListView
). Setting the layout_height
to 0dp
will cause this attribute to be ignored.
当 aLinearLayout
为vertical 时,layout_weight
将影响孩子s ( )的高度。将 设置为将导致此属性被忽略。View
ListView
layout_height
0dp
Example
例子
<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>
When a LinearLayout
is horizontal, then the layout_weight
will effect the widthof the child View
s (ListView
). Setting the layout_width
to 0dp
will cause this attribute to be ignored.
当 aLinearLayout
为水平时,layout_weight
将影响子s ( )的宽度。将 设置为将导致此属性被忽略。View
ListView
layout_width
0dp
Example
例子
<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>
The reason to want to ignore the attribute is that if you didn't ignore it, it would be used to calculate the layout which uses more CPU time.
要忽略该属性的原因是,如果您没有忽略它,它将用于计算占用更多 CPU 时间的布局。
Additionally this prevents any confusion over what the layout should look like when using a combination of the three attributes. This is highlighted by @android developerin an answer below.
此外,这可以防止在使用三个属性的组合时对布局的外观产生任何混淆。@android 开发人员在下面的回答中强调了这一点。
Also, Android Lintand Eclipseboth say to use 0dip
. From that answer below, you can use 0dip
, 0dp
, 0px
, etc since a zero size is the same in any of the units.
此外,Android Lint和Eclipse都说要使用0dip
. 从下面的答案中,您可以使用0dip
、0dp
、0px
等,因为任何单位中的零大小都相同。
Avoid wrap_content on ListView
避免在 ListView 上使用 wrap_content
From Layout_width of a ListView
If you've ever wondered why getView(...)
is called so many times like I have, it turns out to be related to wrap_content
.
如果你曾经想知道为什么getView(...)
像我一样被调用这么多次,结果证明它与wrap_content
.
Using wrap_content
like I was using above will cause all child View
s to be measured which will cause further CPU time. This measurement will cause your getView(...)
to be called. I've now tested this and the number of times getView(...)
is called is reduced dramatically.
wrap_content
像我上面使用的那样使用将导致所有 childView
被测量,这将导致更多的 CPU 时间。此测量将导致您getView(...)
被调用。我现在已经对此进行了测试,并且getView(...)
被调用的次数大大减少了。
When I was using wrap_content
on two ListView
s, getView(...)
was called 3 times for each row on one ListView
and 4 times for each row on the other.
当我wrap_content
在两个ListView
s上使用时getView(...)
,每行被调用 3 次,另一行被调用ListView
4 次。
Changing this to the recommended 0dp
, getView(...)
was called only once for each row. This is quite an improvement, but has more to do with avoiding wrap_content
on a ListView
than it does the 0dp
.
将此更改为推荐的0dp
,getView(...)
每行仅调用一次。这是一个相当大的改进,但更多地是避免wrap_content
在 a 上而ListView
不是在0dp
.
However the suggestion of 0dp
does substantially improve performance because of this.
然而,0dp
由于这个原因,的建议确实大大提高了性能。
采纳答案by Lalit Poptani
First of all you have this,
首先你有这个
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
Never take the ListView's height as wrap_content, that will lead into troubles. Here
is the reason for that and this answer
.
千万不要把ListView的高度当成wrap_content,那样会带来麻烦。Here
是原因 和this answer
。
Further more,
此外,
I searched around but haven't found anything that really explains why Android Lint as well as some Eclipse hints suggests replacing some layout_height and layout_width values with 0dp.
我四处搜索,但没有找到任何能真正解释为什么 Android Lint 以及一些 Eclipse 提示建议将一些 layout_height 和 layout_width 值替换为 0dp 的内容。
Its because you are using layout_weight = "1"
that means your ListView with take the height as much as is available to it. So, in that case there is no need of using layout_height = "wrap_content"
just change it to android:layout_height="0dp"
and ListView's height will be managed by layout_weight = "1"
.
这是因为您正在使用layout_weight = "1"
这意味着您的 ListView 尽可能多地使用它可用的高度。因此,在这种情况下,无需使用,layout_height = "wrap_content"
只需将其更改为android:layout_height="0dp"
,ListView 的高度将由layout_weight = "1"
.
回答by Archie.bpgc
So when android:layout_weight is used on View X and LinearLayout is horizontal, then X's android:layout_width is simply ignored.
所以当 android:layout_weight 用于 View X 并且 LinearLayout 是水平的时,那么 X 的 android:layout_width 会被忽略。
Similar, when android:layout_weight is used on View X and LinearLayout is vertical, then X's android:layout_height is ignored.
类似的,当 android:layout_weight 用于 View X 且 LinearLayout 为垂直时,则忽略 X 的 android:layout_height。
This actually means, that you can put anything in those ignored fields: 0dp or fill_parent or wrap_content. It doesn't matter. But it's recommended to use 0dp so View's do not do extra calculation of their height or width (which is then ignored). This small trick simply saves CPU cycles.
这实际上意味着,您可以在这些被忽略的字段中放入任何内容:0dp 或 fill_parent 或 wrap_content。没关系。但建议使用 0dp,这样 View 就不会额外计算它们的高度或宽度(然后被忽略)。这个小技巧只是节省了 CPU 周期。
from :
从 :
回答by android developer
as far as i know , there is a difference between using 0dp (or 0px btw, it's the same since 0 is 0 no matter what is the unit here ) and the wrap_content or fill_parent (or match_parent, it's the same).
据我所知,使用 0dp(或 0px 顺便说一句,它是相同的,因为 0 是 0,无论这里的单位是什么)和 wrap_content 或 fill_parent(或 match_parent,它是相同的)。
it depends on the weight you use . if you only use weight of 1 , they all look the same , but the meaning is always different , and it is important for performance.
这取决于您使用的重量。如果只使用权重 1,它们看起来都一样,但含义总是不同的,这对性能很重要。
in order to show this , try the following:
为了显示这一点,请尝试以下操作:
<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>
and then try to replace the 0px with match_parent . you will see that the result is very different.
然后尝试用 match_parent 替换 0px 。你会看到结果是非常不同的。
usually , for both better understanding and for better performance , you would want to use 0px.
通常,为了更好的理解和更好的性能,你会想要使用 0px。
回答by Karu
LinearLayout
measures all the children according to the layout_width
/layout_height
values, then divides up the leftover space (which may be negative) according to the layout_weight
values.
LinearLayout
根据layout_width
/layout_height
值测量所有孩子,然后根据值划分剩余空间(可能为负)layout_weight
。
0dp
is more efficient than wrap_content
in this case because it's more efficient to just use zero for the original height and then split the parent's full height based on the weight than to measure the child first and then split the remainder based on the weight.
0dp
比wrap_content
在这种情况下更有效,因为只对原始高度使用零,然后根据体重分割父母的全高比先测量孩子然后根据体重分割其余部分更有效。
So the efficiency comes from not measuring the child. 0dp
should be exactly as efficient (and produce exactly the same result) as match_parent
, or 42px
, or any other fixed number.
所以效率来自不测量孩子。0dp
应该与match_parent
、 或42px
或任何其他固定数字完全一样有效(并产生完全相同的结果)。
回答by Damien
Caution re using android:layout_height="0dp"
注意重新使用 android:layout_height="0dp"
I have found that in a ListView (with the recommended View recycling using convertView, see e.g. http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/), setting android:layout_height="0dp" for the row TextView can lead to text truncation for multi-line text content.
我发现在 ListView 中(使用convertView 推荐的View 回收,参见例如http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/),设置android:layout_height=" 0dp" 行 TextView 可能导致多行文本内容的文本截断。
Whenever a TextView object that was previously used to display a text that fitted in a single line is recycled to display a longer text that needs more than one line, that text is truncated to a single line.
每当以前用于显示适合单行的文本的 TextView 对象被回收以显示需要多于一行的较长文本时,该文本将被截断为单行。
The problem is cured by using android:layout_height="wrap_content"
问题通过使用 android:layout_height="wrap_content" 解决