【问题标题】:How to optimize the recursively embedded layout?如何优化递归嵌入布局?
【发布时间】:2012-09-19 02:58:35
【问题描述】:

我正在构建递归分层布局。这是我的 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 代码中,我使用此布局对项目进行膨胀并将它们嵌入到父级的 replies 布局中,然后对子级重复此操作,从而形成一棵树:

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 不会卡住。一切看起来都很好。

但是原始问题尚未得到解答。

【问题讨论】:

  • 您提出的平面视图层次结构 实际上是对原始问题的有效答案。您最初的问题可以解释为“我正在做这个非常昂贵的操作,我该如何优化它?”有时,正确答案是“少做事”。在 Android 中拥有太多的布局层总是很昂贵。

标签: android android-layout


【解决方案1】:

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

正如您已经看到的那样,问题在于您的布局文件的部门。每次膨胀 message_with_replies.xml 并将其添加到 LinearLayout 时,都会将布局的 dept 增加 2(这会降低性能)。所以,当你达到 7-8 级时,你已经超过了推荐的最大布局部门(如果我没记错的话,是 10 个)。

如何优化这个?

如果您想继续在旧视图中扩展布局,那么没有什么可做的。否则,您会将视图添加到主布局中,而不会在两者之间添加额外的 ViewGroups

当我膨胀a时,通常可以保持层次结构平坦吗 具有其他布局的子项目?我可以给物品充气然后拿走它吗 没有容器的内容?

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

补充:我已经绕过了这个问题。现在我使用边距构建我的树, 所以布局没有嵌入,用户界面也不会卡住。一切 外观和工作正常。

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

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

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

【讨论】:

  • 好吧,“真正的”填充不是我想要的,因为我需要绘制子项之间的连接线,所以我通过在布局中向项目左侧插入一些图像来构建填充。但总体思路很清楚,谢谢。所以我的最终解决方案似乎是正确的(也是唯一可能的)。
猜你喜欢
  • 2014-11-17
  • 1970-01-01
  • 2012-12-21
  • 2021-03-28
  • 1970-01-01
  • 2021-06-18
  • 2020-04-25
  • 2019-01-27
相关资源
最近更新 更多