【问题标题】:ConstraintLayout - centering views with next to each other vertically or horizontallyConstraintLayout - 垂直或水平居中视图
【发布时间】:2017-08-24 22:17:52
【问题描述】:

如何使用ConstraintLayout 将 3 个按钮垂直居中对齐?

明确地说,我想使用ConstraintLayout 将这个简单的布局结构转换为平面 UI

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</LinearLayout>
</FrameLayout>

我得到了一个最接近的解决方案如下

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">


<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/button2"
    />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    tools:layout_conversion_absoluteHeight="48dp"
    tools:layout_conversion_absoluteWidth="88dp"
    tools:layout_conversion_absoluteX="148dp"
    tools:layout_conversion_absoluteY="259dp"
    app:layout_constraintBottom_toTopOf="@+id/button3"
    app:layout_constraintTop_toBottomOf="@+id/button"
    app:layout_constraintRight_toRightOf="parent"/>

<Button
    android:id="@+id/button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"

    app:layout_constraintLeft_toLeftOf="parent"
    tools:layout_conversion_absoluteHeight="48dp"
    tools:layout_conversion_absoluteWidth="88dp"
    tools:layout_conversion_absoluteX="148dp"
    tools:layout_conversion_absoluteY="307dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/button2"
    app:layout_constraintRight_toRightOf="parent"/>

 </android.support.constraint.ConstraintLayout>

但很明显,您可以看到获得的输出与所需的输出不匹配。我不希望 3 个按钮之间有任何边距或空间,我想要的只是将这 3 个按钮垂直居中对齐,就像它们在具有垂直方向的 LinearLayout 中一样。

【问题讨论】:

    标签: android android-layout centering android-constraintlayout


    【解决方案1】:

    适当的解决方案

    很高兴您在这 3 个视图之间创建了链。拥有链,您可以指定链“样式”,它将影响视图沿链轴分布的方式。链样式可以通过视图正下方的“链”按钮控制:

    单击它几次以在所有 3 种模式之间切换:

    传播(默认)

    spread_inside

    打包

    如您所见 - packed 是您想要的。
    设置链样式将导致将以下属性添加到链中的第一个子项,因此您也可以从 XML 中执行此操作:

    app:layout_constraintVertical_chainStyle="packed"

    天真的解决方案

    其他答案中提出的解决方案可能看起来可行,但实际上它不是解决您的问题的正确解决方案。考虑当您有不同高度的视图时的情况,假设底部的视图更大。该解决方案会将中间视图锁定在中心,并将其他视图定位在上方和下方。它不会导致“居中组”(只有中间视图会居中)。您可以在下图中看到比较:

    【讨论】:

    • 非常好的例子展示了这个和简单的解决方案之间的区别。
    • app:layout_constraintVertical_chainStyle="packed"这个属性在哪个视图上运行?
    • 我用最新的studio怎么没有Chain图标。
    • @JPM 我相信为了在编辑器的视图上看到链图标,两个元素之间必须已经存在约束。例如,当垂直堆叠它们时,顶部需要app:layout_constraintBottom_toTopOf="@id/view2" 属性,底部需要app:layout_constraintTop_toBottomOf="@id/view1"。您可以使用可视化编辑器而不是在 XML 中添加这些。或者,您可以在视图层次结构中选择多个视图,右键单击并在那里添加链。
    • 多么直观、自然的居中方法。
    【解决方案2】:

    通过 Android Studio 的“布局编辑器”

    1. 将三个按钮拖放到 Android Studio 的“布局编辑器”中

    2. 通过拖动鼠标同时选择这些按钮

    3. 使用“布局编辑器”中的“打包”按钮将它们垂直打包

    4. 使用“水平居中”按钮将它们水平居中对齐

    5. 使用“垂直居中”按钮将它们垂直居中对齐

    通过 xml

    • 使用将所有这三个按钮打包到 vertically packed chain

       app:layout_constraintVertical_chainStyle="packed"
      
    • 为所有这三个按钮添加左右约束为parent


    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout_editor_absoluteY="25dp"
    tools:layout_editor_absoluteX="0dp">
    
    
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintBottom_toTopOf="@+id/button2"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>
    
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout_conversion_absoluteHeight="48dp"
        tools:layout_conversion_absoluteWidth="88dp"
        tools:layout_conversion_absoluteX="148dp"
        tools:layout_conversion_absoluteY="259dp"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintBottom_toTopOf="@+id/button3"
        app:layout_constraintTop_toBottomOf="@+id/button1"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>
    
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout_conversion_absoluteHeight="48dp"
        tools:layout_conversion_absoluteWidth="88dp"
        tools:layout_conversion_absoluteX="148dp"
        tools:layout_conversion_absoluteY="307dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"/>
    </android.support.constraint.ConstraintLayout>
    

    【讨论】:

    • 请记住,第一个解决方案是一个幼稚的解决方案,而不是一个有效的解决方案。它只会愚弄其他开发人员,请不要提出它......与接受的答案相同。只有第二种解决方案(在我的答案中进行了更详细的描述)是正确将ConstraintLayout 中的视图组居中的正确方法。
    • ConstraintLayout 中,您应该只使用chainStyle 属性,其他解决方案实际上更像是实现“以组为中心”的黑客,这似乎只是从问题中解决问题。如果有一个正确的解决方案与一个错误的解决方案,为什么有人会想要使用不正确的解决方案......?链是专门为解决“分组”问题而设计的。然而,您仍然将不正确的解决方案宣传为可接受的答案以及您的答案的一部分。它只会愚弄其他将来会尝试解决此问题的开发人员,这真的不好。
    【解决方案3】:
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-18
      • 1970-01-01
      • 2013-05-06
      • 2013-07-12
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      相关资源
      最近更新 更多