如何优化递归嵌入布局



我正在构建一个递归层次布局。这是我的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也不会卡住。一切看起来和工作都很好。

然而,最初的问题尚未得到回答。

当我处于顶级或大约从顶部开始2-3层,但随着我深入,布局会做出反应越来越慢。减速是非线性的大约7或8时,UI完全卡住(模拟器发出思考了大约半分钟后出现异常)。

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

如何优化?

如果你想继续在旧视图中扩展布局,那么没有什么可做的。否则,你会在没有额外ViewGroups的情况下将视图添加到主布局中。

当我膨胀一个具有其他布局的子项?我能给这个东西充气然后拿走它吗没有容器的内容?

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

添加:我已经绕过了这个问题。现在我用边距构建我的树,所以布局没有被嵌入,UI也没有被卡住。每件事外观和工作都很好。

这应该是你的第一个选择,而不是一次又一次地膨胀布局,因为这是一个简单得多的解决方案。布局可以通过使用简单的LinearLayout(或RelativeLayout,我不知道你的设置,因为你从布局中删除了布局属性)获得,orientation设置为vertical。在这个布局中,你可以添加所需的视图,并考虑根据你希望这个子级的级别添加边距。如果你想进一步简化,你可以创建一个布局文件,如下所示(如果布局中的Button设置在LinearLayout的顶部,这会起作用):

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

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

最新更新