【问题标题】:Differences between ConstraintLayout and RelativeLayoutConstraintLayout 和 RelativeLayout 的区别
【发布时间】:2016-09-16 05:29:53
【问题描述】:

我对@9​​87654321@ 和RelativeLayout 之间的区别感到困惑。有人可以告诉我它们之间的确切区别吗?

【问题讨论】:

  • ConstraintLayout 主要是为新程序员设计的,这样他们就可以使用可视化编辑器轻松设计布局,而不是通过 XML 手动构建布局。
  • @Jack 对于经验丰富的专家开发人员来说,它也有更深层次的目的
  • @MosesAprico 你是对的,它确实有。但我认为经验丰富的专家开发人员已经有很多其他方法(他们已经知道像RealtiveLayoutLinearLayoutGridLayout 等)来获得他们想要的视图层次结构。
  • @CopsOnRoad 实际上你错了。 Apple 已经做了 5 年多的约束布局。您可以获得任何尺寸的响应式设计,而不必编写大量复杂的布局。当您开始绑定多个视图时,您只需要 3 个基本控件即可创建完全响应式设计。

标签: android android-layout android-relativelayout android-constraintlayout


【解决方案1】:

ConstraintLayout 的目的是通过对每个视图应用一些规则来优化和扁平化布局的视图层次结构以避免嵌套。

规则提醒您RelativeLayout,例如将左侧设置为其他视图的左侧。

app:layout_constraintBottom_toBottomOf="@+id/view1"

RelativeLayout 不同,ConstraintLayout 提供bias 值,用于根据相对于手柄(用圆圈标记)的 0% 和 100% 水平和垂直偏移来定位视图。这些百分比(和分数)提供了跨不同屏幕密度和尺寸的无缝视图定位。

app:layout_constraintHorizontal_bias="0.33" <!-- from 0.0 to 1.0 -->
app:layout_constraintVertical_bias="0.53" <!-- from 0.0 to 1.0 -->

基线句柄(带圆角的长管道,位于圆形句柄下方)用于将视图的内容与另一个视图引用对齐。

方形手柄(在视图的每个角上)用于以 dps 调整视图的大小。

这完全是基于意见和我对ConstraintLayout的印象

【讨论】:

  • 我们仍然可以使用 RelativeLayout 创建扁平化布局,这就是为什么我很困惑 ConstraintLayout 在哪里照顾到 RelativeLayout 不能?
  • RelativeLayout 是二次布局,遭受双重征税。它必须至少测量/布局两次。 ConstraintLayout 不会受到这种性能损失。
  • @Nothing 是的,我们仍然可以使用 RelativeLayout 创建扁平化布局。但是除了这里提到的所有人之外,ConstraintLayout 还允许你使用negative marginssize subviews in predefined ratio。根据Material design,最后一个是在 CardView 中为您的 ImageView 保持 16:9 比例的最可靠方法
  • 有一些布局在RelativeLayout中是不可能的,除非你嵌套一个LinearLayout或者另一个RelativeLayout。例如:将 3 个视图的“堆栈”相对于另一个视图垂直居中
  • @Gak2 如果没有嵌套布局,我在您的示例中看不到任何不可能的事情。也许您对“堆栈”的意思比我的意思不同。我只使用“layout_alignEnd”、“layout_below”、“layout_...”,并且可以用它构建任何类型的堆栈...
【解决方案2】:

相对布局和约束布局等效属性

(1) 相对布局:

android:layout_centerInParent="true"    

(1) 等效约束布局:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

(2) 相对布局:

android:layout_centerHorizontal="true"

(2) 等效约束布局:

app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintEnd_toEndOf="parent"

(3) 相对布局:

android:layout_centerVertical="true"    

(3) 等效约束布局:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"

(4) 相对布局:

android:layout_alignParentLeft="true"   

(4) 等效约束布局:

app:layout_constraintLeft_toLeftOf="parent"

(5) 相对布局:

android:layout_alignParentStart="true"

(5) 等效约束布局:

app:layout_constraintStart_toStartOf="parent"

(6) 相对布局:

android:layout_alignParentRight="true"

(6) 等效约束布局:

app:layout_constraintRight_toRightOf="parent"

(7) 相对布局:

android:layout_alignParentEnd="true"    

(7) 等效约束布局:

app:layout_constraintEnd_toEndOf="parent"

(8) 相对布局:

android:layout_alignParentTop="true"

(8) 等效约束布局:

app:layout_constraintTop_toTopOf="parent"

(9) 相对布局:

android:layout_alignParentBottom="true" 

(9) 等效约束布局:

app:layout_constraintBottom_toBottomOf="parent"

(10) 相对布局:

android:layout_alignStart="@id/view"

(10) 等效约束布局:

app:layout_constraintStart_toStartOf="@id/view"

(11) 相对布局:

android:layout_alignLeft="@id/view" 

(11) 等效约束布局:

app:layout_constraintLeft_toLeftOf="@id/view"

(12) 相对布局:

android:layout_alignEnd="@id/view"  

(12) 等效约束布局:

app:layout_constraintEnd_toEndOf="@id/view"

(13) 相对布局:

android:layout_alignRight="@id/view"

(13) 等效约束布局:

app:layout_constraintRight_toRightOf="@id/view"

(14) 相对布局:

android:layout_alignTop="@id/view"  

(14) 等效约束布局:

app:layout_constraintTop_toTopOf="@id/view"

(15) 相对布局:

android:layout_alignBaseline="@id/view" 

(15) 等效约束布局:

app:layout_constraintBaseline_toBaselineOf="@id/view"

(16) 相对布局:

android:layout_alignBottom="@id/view"

(16) 等效约束布局:

app:layout_constraintBottom_toBottomOf="@id/view"

(17) 相对布局:

android:layout_toStartOf="@id/view"

(17) 等效约束布局:

app:layout_constraintEnd_toStartOf="@id/view"

(18) 相对布局:

android:layout_toLeftOf="@id/view"  

(18) 等效约束布局:

app:layout_constraintRight_toLeftOf="@id/view"

(19) 相对布局:

android:layout_toEndOf="@id/view"

(19) 等效约束布局:

app:layout_constraintStart_toEndOf="@id/view"

(20) 相对布局:

android:layout_toRightOf="@id/view"

(20) 等效约束布局:

app:layout_constraintLeft_toRightOf="@id/view"

(21) 相对布局:

android:layout_above="@id/view" 

(21) 等效约束布局:

app:layout_constraintBottom_toTopOf="@id/view"

(22) 相对布局:

android:layout_below="@id/view" 

(22) 等效约束布局:

app:layout_constraintTop_toBottomOf="@id/view"

【讨论】:

  • 你可以用文字代替图片发帖吗?以便将来对我和其他人都非常有用。
  • 每个开始学习约束布局的人都需要看看这个。谢谢。
  • 这是有用的信息,但只是一个文档转储,并不能解释它们之间的区别。
  • 不,我没有时间查看文档,这当然很有用。并用简单的语言编写。点赞。
【解决方案3】:

报告者 @davidpbr ConstraintLayout 表现

我制作了两个类似的 7-child 布局,每个都有一个父 ConstraintLayoutRelativeLayout。 基于 Android Studio 方法跟踪工具,ConstraintLayout 似乎在 onMeasure 上花费了更多时间,并在onFinishInflate 中执行了额外的工作。

使用的库(support-v4appcompat-v7...):

com.android.support.constraint:constraint-layout:1.0.0-alpha1

设备/Android 版本转载于: 三星 Galaxy S6(SM-G920A。抱歉,没有 Nexus 自动取款机)。安卓5.0.2

快速方法追踪对比:

Github 仓库示例:https://github.com/OnlyInAmerica/ConstraintLayoutPerf

【讨论】:

  • 来自同一个问题:我现在要关闭它——alpha 4/5 带来了相当多的性能改进。我们可能会对其进行更多改进,但这可能要等到 1.0 之后。
  • @Nativ Monotirs->CPU->时间跟踪器图标
  • 在带有 android 6.0.1 的 Nexus 5 上使用约束布局:1.0.1 运行和分析相同的代码,结果如下:相对布局 - 测量 30 毫秒上的初始化 2 毫秒 + 16 毫秒 = 布局上的 62 毫秒 7 毫秒 = 9ms 总计 54 ms 约束布局 - 初始化 7ms 约束布局生成布局参数 + 添加视图 ~ 7*2ms = 14ms On Measure 60ms + 52ms ~ 112ms On Layout 总共 8ms ~ 141ms 相对布局的第一次初始化几乎比约束快三倍。跨度>
  • 引入了约束布局,可以减少嵌套视图层次。因此,更少的层次结构意味着在视图树中从上到下遍历的时间更少。那么,创建约束布局中可能不需要的嵌套视图层次结构并将其与相对布局进行比较的意义何在?
  • 这是有价值的信息,但不能回答问题。它甚至没有解决这个问题。
【解决方案4】:

以下是差异/优势:

  1. 约束布局具有相对布局和线性布局的双重功能:设置视图的相对位置(如相对布局)以及为动态 UI 设置权重(仅在线性布局中才有可能)。

  2. 一个非常强大的用途是通过形成链来对元素进行分组。这样我们就可以形成一组视图,它们作为一个整体可以以所需的方式放置,而无需添加另一层层次结构来形成另一组视图。

  3. 除了权重之外,我们还可以应用水平和垂直偏差,这只是从中心位移的百分比。 (偏差 0.5 表示居中对齐。任何小于或大于的值都表示相应方向上的相应移动)。

  4. 另一个非常重要的特性是它尊重并提供处理 GONE 视图的功能,因此如果通过 java 代码将某些视图设置为 GONE,布局不会中断。更多可以在这里找到: https://developer.android.com/reference/android/support/constraint/ConstraintLayout.html#VisibilityBehavior

  5. 通过使用蓝图和可视化编辑器工具提供自动约束应用的功能,从而可以轻松设计页面。

所有这些功能都会导致视图层次结构扁平化,从而提高性能,还有助于制作响应式和动态 UI,从而更轻松地适应不同的屏幕尺寸和密度。

这里是快速学习的最佳场所: https://codelabs.developers.google.com/codelabs/constraint-layout/#0

【讨论】:

  • 6) ConstraintLayout 可以以预定义的比率medium.com/google-developers/… 调整子视图的大小。例如,当您要将 ImageView 保持在 16:9 时,它会很有用。
【解决方案5】:

一个很大的区别是 ConstraintLayout 尊重约束,即使视图消失了。所以如果你有一个链并且你想让一个视图在中间消失,它不会破坏布局。

【讨论】:

  • 你能给我举个例子吗?假设有 3 个按钮。我将隐藏第二个按钮,第三个按钮附加到第二个按钮,id 为 btn2。假设我隐藏了第二个按钮,那么第三个按钮如何找到第二个按钮的 id?
  • 这不是真的。如果将 Button 的可见性设置为“INVISIBLE”而不是“GONE”,则不会破坏约束。至于我,正如@Nikola 所说,最大的不同是偏见可以帮助您创建更多“响应式”视图。
  • @Nothing 假设按钮在彼此下方。即使您隐藏 tButton 2,它仍然存在于“查看合同”中,无论是在您的 xml 还是代码中。 ConstraintLayout 将尊重它,并且 Button 3 将位于 Button 1 下方。在 RelativeLayout 中,Button 2 消失了,约束也随之消失,因此 Button 3 将位于默认位置,即屏幕的左上角。
  • @zapotec 我尊重其他东西对你来说更重要,但对我来说,这是一个非常酷的区别。修复了我在 RelativeLayout 中唯一讨厌的东西。使用 invisible 不是一种选择,因为它会占用空间。
【解决方案6】:

我能得出的结论是

1) 我们可以在不触及代码的 xml 部分的情况下进行 UI 设计,说实话我觉得 google 复制了 iOS 应用程序中的 UI 设计方式,它会如果您熟悉 iOS 中的 UI 开发,这很有意义,但是在相对布局中很难在不触及 xml 设计的情况下设置约束

2) 其次,它具有 平面视图层次结构,与其他布局不同,比相对布局具有更好的性能,您可能已经从其他答案中看到了

3) 除了相对布局之外,它还有一些额外的东西,例如圆形相对定位,我们可以将另一个视图相对于这个视图以一定的半径以一定的角度定位,而在相对布局中是无法做到的布局

我再说一遍,使用约束布局设计 UI 和在 iOS 中设计 UI 是一样的,所以以后如果你在 iOS 上工作,你会发现使用约束布局会更容易

【讨论】:

    【解决方案7】:

    正式地,ConstraintLayoutmuch faster

    在 Android 的 N 版本中,ConstraintLayout 类提供与RelativeLayout 类似的功能,但成本显着降低。

    【讨论】:

      【解决方案8】:

      除了@dhaval-jivani 的回答。

      我已将项目 github 项目更新为最新版本的约束布局 v.1.1.0-beta3

      我已经测量并比较了 onCreate 方法的时间,以及在 CPU 监视器中可见的 onCreate 方法的开始和最后一个 preformDraw 方法的执行结束之间的时间。所有测试均在配备 android 6.0.1 的三星 S5 mini 上完成 结果如下:

      全新启动(应用启动后第一个屏幕打开)

      相对布局

      创建时:123 毫秒

      上次 preformDraw 时间 - OnCreate 时间:311.3ms

      约束布局

      创建时:120.3 毫秒

      上次 preformDraw 时间 - OnCreate 时间:310ms

      除此之外,我还检查了来自 articlehere the code 的性能测试 并发现循环计数小于 100 的约束布局变体在执行膨胀、测量和布局期间比使用相对布局的变体更快。在旧的 Android 设备上,例如搭载 Android 4.3 的三星 S3,差异更大。

      作为结论,我同意 article 的 cmets:

      重构旧视图是否值得从 RelativeLayout 或 LinearLayout 切换到它?

      一如既往:这取决于?

      我不会重构任何东西,除非您当前的布局层次结构存在性能问题,或者您想对布局进行重大更改。虽然我最近没有测量它,但我在最近的版本中没有发现任何性能问题。所以我认为你应该可以安全地使用它。但是——正如我所说——不要仅仅为了迁移而迁移。只有在需要并从中受益时才这样做。 不过,对于新布局,我几乎总是使用 ConstraintLayout。与我们之前的相比,它好多了。

      【讨论】:

        【解决方案9】:

        真正要问的问题是,是否有任何理由使用约束布局以外的任何布局?我相信答案可能是否定的。

        对于那些坚持它们是针对新手程序员等的人,他们应该提供一些理由让它们不如任何其他布局。

        约束布局在各个方面都更好(它们的 APK 大小确实需要 150k。)。它们更快、更简单、更灵活、对更改做出更好的反应、在项目消失时解决问题、它们更好地适应完全不同的屏幕类型并且它们不使用一堆嵌套循环那么长为所有内容绘制树结构。你可以把任何东西放在任何地方,关于任何东西,任何地方。

        在 2016 年年中,他们有点搞砸了,视觉布局编辑器还不够好,但他们的观点是,如果你有一个布局,你可能需要认真考虑使用约束布局,即使它与RelativeLayout 甚至是简单的LinearLayout 做同样的事情。 FrameLayouts 显然仍有其目的。但是,目前我看不到其他任何东西。如果他们从这个开始,他们就不会添加任何其他内容。

        【讨论】:

        • 有没有证据证明它更快?
        • 是的。它更快。布局在单个求解器中向下,而不是遍历树。对于大多数事情,这并不重要,因为它是在调用布局时完成的。但是,视图树的事情虽然简单,但在需要调用的视图内创建了一堆视图。虽然理论上更好,但实际上在一段代码中执行布局比遍历整个视图树要容易得多。观看次数越多,效果就越令人印象深刻,但这是 5 月的基准:medium.com/@krpiotrek/constraintlayout-performance-c1455c7984d7
        • 我面临另一个问题,我应该替换我正在开发的应用程序中所有现有的 Relativelayouts 吗?它会显着提高性能吗?
        • @SreekanthKarumanaghat 似乎您永远不会收回替换那些所需的时间,因为时间切换会节省您的时间。在大多数情况下,我们说的是 3.5ms 周期下降到 3.25ms。如果它为您提供了额外的功能或您需要的东西,那么可以肯定,但纯粹是出于速度原因。虽然我们正在谈论点击转换按钮。
        【解决方案10】:

        我注意到的唯一区别是,通过拖放在相对布局中设置的事物会自动推断出相对于其他元素的尺寸,因此当您运行应用程序时,所见即所得。但是,在约束布局中,即使您在设计视图中拖放元素,当您运行应用程序时,事情也可能会发生变化。这可以通过手动设置约束来轻松解决,或者更冒险的做法是右键单击组件树中的元素,选择约束布局子菜单,然后单击“推断约束”。希望这会有所帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-21
          • 1970-01-01
          • 1970-01-01
          • 2021-08-01
          • 2018-04-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多