【问题标题】:Button text don't wrap when used with ConstraintLayout与 ConstraintLayout 一起使用时,按钮文本不换行
【发布时间】:2020-03-06 21:42:19
【问题描述】:

我有 2 个彼此相邻的按钮(链接),并且应用程序中有 2 种可能的状态,要么只有左侧按钮可见,在这种情况下它应该水平居中,要么两者都可见,在这种情况下它们都可见应该水平居中。这一切都有效,但是按钮中有多个单词,并且在小屏幕上,按钮都被剪裁而不是换行。要修复此设置,将两个按钮的宽度设置为 0dp 可以正常工作,但在这种情况下,按钮会变得尽可能宽,因此在较大的屏幕上或只有一个按钮可见时,它看起来不正确。我的问题是如何在使用 ConstraintLayout 时将单词包装在按钮中?如何约束按钮,使它们正确包裹并且不会变得比需要的宽?使用LinearLayout,这一切都是开箱即用的,但我想使用ConstraintLayout。我尝试在两个按钮上设置 app:layout_constrainedWidth="true" 但这不起作用,它将只包装第一个按钮,如果第二个按钮有足够长的文本,它将不存在。

更新:我将示例中的按钮文本更新为更长。

XML:

            <Button
                android:id="@+id/button1"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="8dp"
                android:layout_marginRight="8dp"
                android:text="Long text for first button"
                app:layout_constraintEnd_toStartOf="@+id/button2"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintHorizontal_chainStyle="packed"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/objectAboveButtons"
                app:layout_goneMarginEnd="0dp"
                app:layout_goneMarginRight="0dp" />

            <Button
                android:id="@+id/button2"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginLeft="8dp"
                android:layout_marginTop="16dp"
                android:text="Long text for second button"
                android:visibility="gone"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toEndOf="@+id/button1"
                app:layout_constraintTop_toBottomOf="@+id/objectAboveButtons" />

【问题讨论】:

  • 很难说哪里出了问题,因为我试图复制这段代码,它的工作方式就像你需要的那样,只是约束几乎没有变化。
  • 我匿名化了文本,也许“按钮 1 的文本”有点短,如果你让它长一点,它会左右剪辑,至少在我的三星 Galaxy s4 上是这样。
  • 所以需要让文本进入第二行等等?我检查了一些答案。您可以以编程方式设置文本,包括 \n 以使宽度正确。
  • 是的,例如,如果 layout_width 为 0dp,则单词会在需要时自动换行,并且两个按钮的宽度相同,但这种方法的问题在于这些按钮将占用所有可用空间,而不是仅按需要的宽度。我希望按钮可以根据需要扩展,但不要超出它们的需要。我不确定以编程方式设置\n,因为如果不需要,它不应该换行。
  • 如果您可以指定所需的宽度,然后将其应用于按钮文本,它将起作用。因为唯一改变的是文本,并且只有当getWidth() 更大以至于它可以容纳时。我知道,这不是一个优雅的解决方案。但如果你试一试:)

标签: android android-layout android-constraintlayout


【解决方案1】:

在按钮中使用app:layout_constraintWidth_default="wrap",并将宽度设置为0dp,而不是wrap_content,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:id="@+id/button1"
            style="@style/Widget.AppCompat.Button.Colored"
            android:layout_height="wrap_content"
            android:layout_width="0dp"
            app:layout_constraintWidth_default="wrap"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:text="Long text for first button"
            app:layout_constraintEnd_toStartOf="@+id/button2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintHorizontal_weight="1"/>

    <Button
            android:id="@+id/button2"
            style="@style/Widget.AppCompat.Button.Colored"
            android:layout_height="wrap_content"
            android:layout_width="0dp"
            app:layout_constraintWidth_default="wrap"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:text="Long text for second button"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/vertical_guideline_50_pc"
            app:layout_constraintHorizontal_weight="1"/>

    <android.support.constraint.Guideline
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/vertical_guideline_50_pc"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

当按钮包含较大的文本(如问题中提供的文本)时,我使用Guideline 在按钮之间均匀分配宽度。当其可见性处于GONE 状态时,以编程方式将Button2app:layout_constraintStart_toEndOfGuideline 更改为Button1

if (button2.visibility == View.GONE) {
    ...
     constraintSet.connect(R.id.button2, ConstraintSet.START, R.id.button1, ConstraintSet.END, 0);
}

问题中提供的较长文本的屏幕截图,两个按钮都环绕在它们周围:

按钮 2 消失后的屏幕截图:

【讨论】:

  • 这几乎奏效了,所以我会批准它。我还必须添加一个水平偏置约束,并在两个按钮都显示时将按钮移向中心,将按钮 1 的偏置设置为 1.0,将按钮 2 设置为 0.0,以便它们在更大的屏幕或横向上居中,但是当只有第一个按钮时显示偏差必须为 0.5,否则它会填满整个宽度。我也不认为按钮需要重量。谢谢。
  • 添加 app:layout_constraintWidth_default="wrap" 是我所需要的。为什么我无法想象的框架不会自动处理这个问题。谢谢你的回答!
【解决方案2】:

虽然 SaadAAkash 的答案是正确的,但至少在 androidx 约束布局 1.1.3 中,layout_constraintWidth_default="wrap" 已被弃用,正确的方法如下:

  1. layout_width="0dp" 替换为layout_width="wrap_content"
  2. layout_constraintWidth_default="wrap" 替换为layout_constrainedWidth="true"

它应该产生相同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 2018-09-03
    • 2018-03-03
    • 2018-05-14
    • 2015-06-17
    • 2017-06-25
    • 2021-11-20
    相关资源
    最近更新 更多