【问题标题】:ConstraintLayout Treats Multiple Horizontal Chains DifferentlyConstraintLayout 以不同方式处理多个水平链
【发布时间】:2018-03-11 02:42:54
【问题描述】:

我正在尝试使用ConstraintLayout 设置我认为应该是一个简单的布局我有一系列文本条目,标签的大小可以随语言而变化。标签的右侧有一个障碍,因此即使标签长度发生变化,文本条目也会保持对齐。

我希望文本条目为标称大小(在此示例中,顶部为 200dp,其他为 150dp),但如果标签较长且屏幕较小,则能够根据需要缩小以适应屏幕.在横向模式下,或在更大的屏幕上,条目应该是它们的最大尺寸并靠着屏障向左对齐。

经过大量的试验和错误,我得到了下面的布局,通过将两个链设置为“spread_inside”并将最后一个链设置为“packed”。将它们全部设置为 spread_inside 会打乱布局(entry_2 缩小到最小尺寸)。

这闻起来像是在未来的ConstraintLayout 更新中将停止以这种方式工作的东西(这是使用 com.android.support.constraint:constraint-layout:1.1.0-beta5)。使用 beta4 时,此布局的行为有所不同(同样错误,但不同的是,beta4 将它们全部对齐在屏幕的右侧)。

我在这里遗漏了什么吗?还有其他人有类似的连锁模式吗?有更好的方法吗?

<?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"
    android:padding="16dp"
    tools:context="com.mypackage.testapp.MainActivity">

    <TextView
        android:text="Label 1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_1"
        app:layout_constraintBottom_toBottomOf="@+id/entry_1"
        android:id="@+id/label_1" />

    <EditText
        android:id="@+id/entry_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:inputType="text"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintHorizontal_weight="100.0"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintRight_toLeftOf="@+id/space_1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_max="200sp"
        app:layout_constraintWidth_min="100sp" />

    <Space
        android:id="@+id/space_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/entry_1"
        app:layout_constraintHorizontal_weight="0.01"
        app:layout_constraintTop_toTopOf="@+id/entry_1"
        app:layout_constraintBottom_toBottomOf="@+id/entry_1"/>

    <TextView
        android:text="Label 2 Is very very long"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_2"
        app:layout_constraintBottom_toBottomOf="@+id/entry_2"
        android:id="@+id/label_2" />

    <EditText
        android:id="@+id/entry_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:inputType="text"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintHorizontal_weight="100.0"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintRight_toLeftOf="@+id/space_2"
        app:layout_constraintTop_toBottomOf="@+id/entry_1"
        app:layout_constraintWidth_max="150sp"
        app:layout_constraintWidth_min="100sp" />

    <Space
        android:id="@+id/space_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/entry_2"
        app:layout_constraintHorizontal_weight="0.01"
        app:layout_constraintTop_toTopOf="@+id/entry_2"
        app:layout_constraintBottom_toBottomOf="@+id/entry_2"/>

    <TextView
        android:text="Label Three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_3"
        app:layout_constraintBottom_toBottomOf="@+id/entry_3"
        android:id="@+id/label_3" />

    <EditText
        android:id="@+id/entry_3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:inputType="text"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_weight="100.0"
        app:layout_constraintLeft_toRightOf="@+id/guideline"
        app:layout_constraintRight_toLeftOf="@+id/space_3"
        app:layout_constraintTop_toBottomOf="@+id/entry_2"
        app:layout_constraintWidth_max="150sp"
        app:layout_constraintWidth_min="100sp" />

    <Space
        android:id="@+id/space_3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/entry_3"
        app:layout_constraintHorizontal_weight="0.01"
        app:layout_constraintTop_toTopOf="@+id/entry_3"
        app:layout_constraintBottom_toBottomOf="@+id/entry_3"/>

    <android.support.constraint.Barrier
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:barrierDirection="right"
        app:constraint_referenced_ids="label_1,label_2,label_3" />

</android.support.constraint.ConstraintLayout>

编辑:

我向 Google 的 ConstraintLayout 团队报告了这个问题,他们确认这是一个错误。一旦修好,我应该可以不用复杂的链条来做到这一点。

【问题讨论】:

    标签: android android-constraintlayout constraint-layout-chains


    【解决方案1】:

    Android 开发团队确认这是一个错误,并已在 beta6 版本中修复。布局现在无需任何链或空间即可工作(下面的解决方案是他们在票证中建议的)。

    https://issuetracker.google.com/issues/74469361

    <TextView
        android:id="@+id/label_1"
        android:tag="48,103,136,57"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Label 1"
        app:layout_constraintBottom_toBottomOf="@+id/entry_1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_1" />
    
    <EditText
        android:id="@+id/entry_1"
        android:tag="505,63,512,136"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_marginStart="8dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_max="200sp"
        app:layout_constraintWidth_min="100sp" />
    
    <TextView
        android:id="@+id/label_2"
        android:tag="48,254,442,57"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Label 2 Is very very long"
        app:layout_constraintBottom_toBottomOf="@+id/entry_2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_2" />
    
    <EditText
        android:id="@+id/entry_2"
        android:tag="505,214,450,136"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_marginStart="8dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/entry_1"
        app:layout_constraintWidth_max="150sp"
        app:layout_constraintWidth_min="100sp" />
    
    <TextView
        android:id="@+id/label_3"
        android:tag="48,405,218,57"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Label Three"
        app:layout_constraintBottom_toBottomOf="@+id/entry_3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@+id/entry_3" />
    
    <EditText
        android:id="@+id/entry_3"
        android:tag="505,365,450,136"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_marginStart="8dp"
        android:inputType="text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/entry_2"
        app:layout_constraintWidth_max="150sp"
        app:layout_constraintWidth_min="100sp" />
    
    <android.support.constraint.Barrier
        android:id="@+id/guideline"
        android:tag="490,48,0,0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:barrierDirection="right"
        app:constraint_referenced_ids="label_1,label_2,label_3" />
    

    【讨论】:

      【解决方案2】:

      我的猜测是你并没有真正建立一个连锁店。

      https://developer.android.com/training/constraint-layout/index.html

      只有当链的每一端都被约束到同一轴上的另一个对象时,链才能正常工作

      对于正确的链条,您的标签也需要成为其中的一部分。您可能只是放弃链属性并将编辑文本限制为障碍和父权限。

      希望对您有所帮助。

      【讨论】:

      • 链在屏障和父权限之间。水平链的正确轴上是否没有考虑垂直障碍?我尝试按照您的建议将 EditTexts 绑定到右侧,但这只是将障碍物移过并将事物向右对齐。
      • 我的意思是我认为一条链应该从父级左侧/开始到父级右侧/结束。由于您的从障碍开始,因此它可能不是真正的链,因此计算不正确。您可以尝试将layout_width 设置为wrap_content,并设置minWidthmaxWidth 属性而不是约束等效项。
      • 链不必运行父级的整个宽度/高度。您可以水平排列 3 个视图,但只有正确的两个是一个链(具有“双向约束”,来自您发布的链接)。示例:视图 A 从左到左绑定到父级,视图 B 从左到右绑定到 A,从右到左绑定到 C,视图 C 从左到右绑定到 B,从右到右到父级。然后B和C形成一条从A右边到父右边的链。设置最小/最大宽度和 wrap_content 以最小宽度启动它,如果屏幕很小,让它在你输入时从屏幕上展开。
      【解决方案3】:

      试试Relative Layout

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout
          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"
          android:padding="16dp">
      
          <TextView
              android:id="@+id/label_1"
              android:text="Label 1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:textSize="20sp"/>
          <EditText
              android:id="@+id/entry_1"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_margin="15dp"
              android:layout_alignBaseline="@+id/label_1"
              android:layout_toEndOf="@+id/label_1"
              android:maxLength="20"
              android:textSize="20sp"
              android:inputType="text" />
          <TextView
              android:id="@+id/label_2"
              android:text="Label 2"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="20dp"
              android:textSize="20sp"
              android:layout_below="@+id/label_1"/>
          <EditText
              android:id="@+id/entry_2"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_margin="15dp"
              android:layout_alignBaseline="@+id/label_2"
              android:layout_toEndOf="@+id/label_2"
              android:maxLength="20"
              android:textSize="20sp"
              android:inputType="text" />
          <TextView
              android:id="@+id/label_3"
              android:text="Label 3"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="20dp"
              android:textSize="20sp"
              android:layout_below="@+id/label_2"/>
          <MultiAutoCompleteTextView
              android:id="@+id/entry_3"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_margin="15dp"
              android:layout_alignBaseline="@+id/label_3"
              android:layout_toEndOf="@+id/label_3"
              android:maxLength="200"
              android:textSize="20sp"/>
      </RelativeLayout>
      

      编辑:这应该是表单的基本结构,如果ConstraintLayout 不是唯一选项时提供。

      • 使用Relative Layout就可以了,Table Layout这里不需要
      • android:maxLength设置值
      • 要包含更多文本字符,请使用MultiAutoCompleteTextView

      【讨论】:

      • 这是我最初的,但它不能像呈现的那样工作(在表格中设置为 0dp 时,EditText 宽度不会扩展,并且手动设置 EditText 的宽度不适应小屏幕)。
      • 好的。您是否尝试过 layout_width = match_parent 并根据您对 EditText 的需要设置 layout_marginEnd
      • 是的,我有。对所有这些使用 match_parent 会创建大约 1em 宽的 EditText。如果我设置其中一个的宽度,那么它们都有匹配的大小。设置结束/右边距不会阻止它离开屏幕,只是在右边添加一个边距。它可能看起来像是停在屏幕边缘,但如果您继续输入,光标只会移动到隐藏部分。
      • 是的,你是对的。我之前没有测试过。谢谢@TylerV 现在,我已经更新了我的答案。 :)
      • 这个版本有效,但仍然错过了我试图通过 ConstraintLayout 获得的一些行为。 1) 当标签长度不同时,EditTexts 不再垂直对齐,2) EditTexts 跨越整个屏幕宽度,这使得它们在大屏幕或横向模式下太长。设置 maxLength 只是限制可以输入到框中的字符数,而不是框大小本身。我希望 EditText 宽度“尽可能宽但不比 X 宽”
      猜你喜欢
      • 2020-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 2020-03-14
      • 2018-10-02
      • 1970-01-01
      相关资源
      最近更新 更多