ConstraintLayout与CoordinatorLayout的区别?

67
要实现在安卓中正确的Material Design,应该使用哪个布局方式:ConstraintLayout还是CoordinatorLayout?
4个回答

90

CoordinatorLayout是一个功能强大的FrameLayout。

CoordinatorLayout

CoordinatorLayout主要用于两种情况:

  • 作为顶层应用程序装饰或工具栏布局
  • 作为包含一个或多个子视图的交互容器

默认情况下,如果将多个子项添加到FrameLayout中,它们会重叠在一起。最好将FrameLayout用于只包含单个子视图的情况。 CoordinatorLayout的主要吸引力在于其协调其内部视图的动画和过渡的能力。通过为CoordinatorLayout的子视图指定Behavior行为,可以在单个父级中提供许多不同的交互,并且这些视图也可以彼此互动。当作为CoordinatorLayout的子项使用时,视图类可以使用CoordinatorLayout.DefaultBehavior注释来指定默认行为。

行为可用于实现各种交互和其他布局修改,从滑动抽屉和面板到可滑动消失的元素和随着移动和动画而粘附到其他元素的按钮。

ConstraintLayout是一个功能强大的ViewGroup,类似于RelativeLayout,但比RelativeLayout更灵活。

ConstraintLayout

ConstraintLayout允许您创建具有平面视图层次结构(无嵌套视图组)的大型复杂布局。与RelativeLayout类似,所有视图都根据兄弟视图和父布局之间的关系进行布局,但它比RelativeLayout更灵活,并且更容易在Android Studio的布局编辑器中使用。

  • 一旦开始使用ConstraintLayout,您无需使用任何其他ViewGroup,如RelativeLayoutLinearLayoutFrameLayout

目前可以使用各种类型的约束条件:

  • 相对定位
  • 边距
  • 居中定位
  • 圆形定位
  • 可见性行为
  • 尺寸约束条件
  • 虚拟帮助对象
  • 优化器

在Android中实现正确的Material Design:ConstraintLayout还是CoordinatorLayout?

你可能需要同时使用 ConstraintLayoutCoordinatorLayout 来构建高效的UI和材料动画。
下面是一个常见的示例,使用了 CoordinatorLayoutConstraintLayout
- 将 Coordinatorlayout 用作顶层应用程序装饰。通常用于布局 AppBarLayoutFloatingActionButton 和屏幕的主体部分,如 NestedScrollView。在 NestedScrollView 内部,使用 ConstraintLayout 将其余布局描述为扁平层次结构。
<androidx.coordinatorlayout.widget.CoordinatorLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent">

      <androidx.core.widget.NestedScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

          <!-- Your scrolling content -->
          <androidx.constraintlayout.widget.ConstraintLayout
              ...>

              <!-- body of constraint layout -->

              <Button android:id="@+id/button" ...
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toRightOf="parent/>


          </androidx.constraintlayout.widget.ConstraintLayout>
     </androidx.core.widget.NestedScrollView>

     <com.google.android.material.appbar.AppBarLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent">
      <androidx.appcompat.widget.Toolbar
             ...
             app:layout_scrollFlags="scroll|enterAlways"/>
      <com.google.android.material.tabs.TabLayout
             ...
             app:layout_scrollFlags="scroll|enterAlways"/>
      </com.google.android.material.appbar.AppBarLayout>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

上述片段是什么意思?以下是翻译:

  • 我们将androidx.coordinatorlayout.widget.CoordinatorLayout 放置在根布局中。并且我们将androidx.core.widget.NestedScrollViewcom.google.android.material.appbar.AppBarLayout作为直接子项。
  • 我们为androidx.core.widget.NestedScrollView 定义了app:layout_behavior = "com.google.android.material.appbar.AppBarLayout $ ScrollingViewBehavior"属性。这是关键点。我们为NestedScrollView 定义了一个行为。也就是说,我们告诉协调器布局(CoordinatorLayout),NestedScrollView依赖于AppBarLayout

    • 当然,行为本身不做任何事情,但协调器布局会根据指示进行相应操作,并帮助拦截触摸事件、窗口插图、测量、布局和嵌套滚动。所以,在这里,它将NestedScrollView放置在我们指定的AppBarLayout下方。很酷,对吧?
  • 我们将ConstraintLayout放置在NestedScrollView内部,使其可滚动。就像我们已经讨论过的那样,ConstraintLayout用于将子视图对齐在约束布局(ConstraintLayout)的范围内。

我可以在另一个ConstraintLayout中添加ConstraintLayout吗?

当然可以,您可以根据设计要求使用任何组合来对齐视图。

我可以在另一个CoordinatorLayout中添加CoordinatorLayout吗?

这不是常规做法。协调器布局最常见的用例是作为顶级应用程序装饰,用于协调其他直接子项之间的关系。但是,如果您真的想嵌套CoordinatorLayout,您可以通过创建扩展CoordinatorLayout并实现NestedScrollingChild的自定义CoordinatorLayout来实现,并将滚动事件传递给父CoordinatorLayout。


额外加分

您可以使用功能强大的MotionLayout ,它是ConstraintLayout 的子类,用于构建动画。 您可以查看这个例子,其中使用了MotionLayout 进行自定义动画。


赞!这是我在SO上读过的最好的答案之一。 - John

78

CoordinatorLayout旨在成为activity的顶层布局,用于管理Behaviors(例如交互和动画)。

ConstraintLayout的主要目标是提供一种方便的方式来创建具有多个子元素的平面布局(比RelativeLayout更加强大)。

因此,CoordinatorLayout用于管理activity组件的复杂行为(特别是动画),而ConstraintLayout用于组件的适当放置(特别是列表项)。


16

看起来你(几乎)总是使用CoordinatorLayout,有时在内部使用ConstraintLayout。请参考以下资源

  • The codelab at https://codelabs.developers.google.com/codelabs/material-design-style/index.html#3 only uses a CoordinatorLayout

  • The example android-sunflower app ("illustrating Android development best practices") uses neither for the top-level activity, but uses both inside its fragment_plant_detail.xml, with the ConstraintLayout being inside the CoordinatorLayout:

    <layout ...>
    <data .../>
    <android.support.design.widget.CoordinatorLayout ...>
        <android.support.design.widget.AppBarLayout ...>
            <android.support.design.widget.CollapsingToolbarLayout ...>
                <ImageView... />
                <android.support.v7.widget.Toolbar... />
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>
        <android.support.v4.widget.NestedScrollView ...>
            <android.support.constraint.ConstraintLayout ...>
                <TextView.../>
                <TextView... />
            </android.support.constraint.ConstraintLayout>
        </android.support.v4.widget.NestedScrollView>
        <android.support.design.widget.FloatingActionButton ... />
    </android.support.design.widget.CoordinatorLayout>
    </layout>
    

3
这是一个很好的例子。使用<layout>进行数据绑定;在<data>中传递viewmodel参数;用<CoordinatorLayout>来协调和动画化工具栏、浮动操作按钮等;使用<ConstraintLayout>来容纳视图。 - Sergio

1

@Darish有一个很好的、全面的答案。我同意他说的一切,只是想补充一点信息。根据我的经验,大多数情况下,父视图使用Constraint Layout就足够了。当你需要引入Coordinator Layout时,是因为你有特定的行为需要管理(例如底部表单)。如果你不会使用它的行为能力,或者尝试操作多个视图,那么Coordinator Layout会比它值得的麻烦。

我以前写过一篇博客文章,用插图说明了Coordinator和Constraint布局的区别和用法。如果您感兴趣,请在这里查看。

我还要推荐MotionLayout作为一种非常全面的方法,可以在不增加太多代码的情况下向您的布局添加动画效果!这个带有示例的Google开发者系列 是学习MotionLayout的好方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接