如何优化递归嵌入式布局?

时间:2012-09-16 09:50:00

标签: android android-layout

我正在构建一个递归的分层布局。这是我的message_with_replies.xml(我删除了对齐属性和一些项目,以明确这个想法):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
    <Button
        android:id="@+id/toggleReplies"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/button_expand_replies" />
    <LinearLayout
        android:id="@+id/replies"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>
</RelativeLayout>

在Java代码中,我使用此布局对项目进行了膨胀,并将它们嵌入到父项的回复布局中,然后对子项重复此操作,以便它们形成树:

root item
- child 0 of root
- - child 0 of child 0 of root
- - child 1 of child 0 of root
- - - child 0 of child 1 of child 0 of root
- child 1 of root
- child 2 of root
- child 3 of root
- - child 0 of child 3 of root

当我处于顶层或从顶部开始大约2-3级时,一切看起来都很好,但是当我走得更深时,布局反应越来越慢。减速是非线性的,在大约7或8的深度上,UI完全卡住(模拟器在思考了大约半分钟后引发异常)。

显然,问题是嵌入式布局。我将线性布局嵌入到相对布局中,因此我的层次结构的每个新级别都意味着在UI布局方面有两个额外的嵌入。

如何优化?

我可以尝试摆脱线性布局,但我希望这不会解决问题,但只会将其推迟到更深层次,因为我仍然会进行嵌入。

当我使用更多布局对子项目进行充气时,通常是否可以保持层次结构平整?我可以给项目充气,然后在没有容器的情况下取出它的内容吗?

已添加:我已绕过问题。现在我使用边距构建我的树,因此布局不会嵌入,并且UI不会卡住。一切看起来都很好。

但原来的问题尚未得到解答。

1 个答案:

答案 0 :(得分:3)

  

当我处于最顶层或大约时,一切看起来都很好   从顶部开始2-3级,但随着我更深入,布局会做出响应   越来越慢。减速是非线性的,并且在深度上   大约7或8个UI完全卡住(模拟器引发了一个   思考了大约半分钟后的异常。)

正如您已经看到的那样,问题是布局文件的部门。每次您将message_with_replies.xml充气并将其添加到LinearLayout时,您的布局部门都会增加2(这会降低性能)。所以,当你达到7-8级别时,你已经超过了建议的最大布局部门(10,如果我没有弄错的话),那就非常多了。

  

如何优化?

如果您想继续在旧视图中对布局进行充气,那么没有太多事情要做。否则,您可以将视图添加到主布局,而不需要额外的ViewGroups

  

通常可以在我充气时保持层次结构平整   具有更多布局的子项目?我可以给项目充气,然后拿走它   没有容器的内容?

如果只将Views添加到布局中,您将保持层次结构平整。只要您将ViewGroups添加到ViewGroups(就像在代码中一样),您就会增加层次结构的部门。避免添加不必要的ViewGroups(在某些情况下)的选项是使用merge标记(您可以找到更多详细信息here)。

  

补充:我绕过了这个问题。现在我使用边距构建我的树,   所以布局没有嵌入,UI也不会卡住。一切   看起来很好。

这应该是您的第一选择,而不是一次又一次地膨胀布局,因为它是一个更简单的解决方案。在LinearLayout设置为{{RelativeLayout的情况下,可以使用简单的orientation(或vertical,我不知道您从布局中删除布局属性时的设置)来获取布局1}}。在此布局中,您将添加所需的视图,同时考虑根据您希望此孩子的级别添加边距。如果你想简化更多的事情,你会创建一个如下所示的布局文件(如果布局中的Button设置在LinearLayout之上,则此方法有效):

<merge>
    <Button android:id="@+id/toggleReplies">
    <!-- content of the replies at this level -->
</merge>

在扩充此布局后,您需要设置填充(第一级为x填充,第二级为2x,第三级为3x等),然后将其添加到LinearLayout