垂直限制多个视图以永不越线?
Constrain many views vertically to never cross a line?
我有一个包含许多输入的注册表单,每个输入的边距为 8dp。它还有一个标题,marginBottom 为 24dp。在某些情况下,有些输入必须隐藏。
所以我希望第一个,无论它是什么,与标题有特定的 24dp 边距,并且彼此之间有 8dp 的边距。
我想用ConstraintLayout解决这个问题。这是我的 xml:
<?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:id="@+id/cho_card_document"
tools:background="#FF0000"
tools:ignore="SpUsage, RtlHardcoded,RtlSymmetry"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="274dp"
android:layout_height="200dp"
android:background="@drawable/cho_shape_round_white_background"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50dp"
android:id="@+id/cho_ticket_view"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/title"
tools:text="Awesome Title Form"
android:layout_marginTop="24dp"
android:layout_marginLeft="16dp"
app:layout_constraintRight_toRightOf="@+id/cho_ticket_view"
app:layout_constraintLeft_toLeftOf="@+id/cho_ticket_view"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input1"
tools:text="Awesome Input 1"
android:layout_marginTop="24dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/title" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input2"
tools:text="Awesome Input 2"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/input1" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input3"
tools:text="Awesome Input 3"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/input2" />
</android.support.constraint.ConstraintLayout>
编辑:我已经用实际实现和一些屏幕截图更新了布局。
之前:
隐藏 input1
后,我 input2
离 title
太近了
最佳解决方案是将它们放在一个 Contraintlayout 中。然后将该布局限制在标题表单底部所需的边距处。那么当你隐藏input 1时,input 2最多只能向上移动并替换input 1的位置,但不会移动整体布局。希望这有帮助
<RelativeLayout
android:layout_margin="24dp"
android:id="@+id/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/title"
android:text="Awesome Title Form"
/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="8dp"
android:layout_below="@+id/title1"
android:id="@+id/subject"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input1"
android:text="Awesome Input 1"
/>
<TextView
android:layout_below="@+id/input1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input2"
android:text="Awesome Input 2"
/>
<TextView
android:layout_below="@+id/input2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input3"
android:text="Awesome Input 3"
/>
</RelativeLayout>
你可以通过做两件事来解决这个问题:
- 重新平衡垂直边距的分配方式
- 在您的标题和三个输入视图之间创建垂直 "chain"
重新平衡利润很容易。将 input1
视图上的 android:layout_marginTop="24dp"
更改为使用 8dp
(就像 input2
和 input3
),并将 android:layout_marginBottom="16dp"
添加到 title
视图。这样,无论您输入的哪个视图是 hidden/visible,标题和第一个输入之间的总间距将始终为 24dp。
创建链有点复杂。链中的每个视图都必须同时具有顶部和底部约束。链中的第一个视图应将其顶部约束为 cho_ticket_view
,链中的最后一个视图应将其底部约束为 cho_ticket_view
,其他所有视图(在两个方向上)应约束为它的邻居。
这是它的样子(为简洁起见省略了其他属性):
<TextView
android:id="@+id/title"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view"
app:layout_constraintBottom_toTopOf="@+id/input1"/>
<TextView
android:id="@+id/input1"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input2"/>
<TextView
android:id="@+id/input2"
app:layout_constraintTop_toBottomOf="@+id/input1"
app:layout_constraintBottom_toTopOf="@+id/input3"/>
<TextView
android:id="@+id/input3"
app:layout_constraintTop_toBottomOf="@+id/input2"
app:layout_constraintBottom_toBottomOf="@+id/cho_ticket_view"/>
设置好这八个约束后,这四个视图现在就是一个 "chain"。可以通过向链的 "head" 添加额外的属性来配置链(第一个视图,即 title
给你)。
您将需要 title
视图中的这些属性:
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
使链成为 "packed" 链意味着它将所有额外的 space 放在链外(而不是链中的视图之间)。给它一个 0
的垂直偏差意味着所有额外的 space 都在链的下方(而不是上方)。
这是完整的 XML,结合了上述所有内容:
<?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:id="@+id/cho_card_document"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="#FF0000"
tools:ignore="SpUsage, RtlHardcoded,RtlSymmetry">
<View
android:id="@+id/cho_ticket_view"
android:layout_width="274dp"
android:layout_height="200dp"
android:layout_marginTop="50dp"
android:background="@drawable/cho_shape_round_white_background"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view"
app:layout_constraintLeft_toLeftOf="@+id/cho_ticket_view"
app:layout_constraintRight_toRightOf="@+id/cho_ticket_view"
app:layout_constraintBottom_toTopOf="@+id/input1"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
tools:text="Awesome Title Form"/>
<TextView
android:id="@+id/input1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input2"
tools:text="Awesome Input 1"/>
<TextView
android:id="@+id/input2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/input1"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input3"
tools:text="Awesome Input 2"/>
<TextView
android:id="@+id/input3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/input2"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toBottomOf="@+id/cho_ticket_view"
tools:text="Awesome Input 3"/>
</android.support.constraint.ConstraintLayout>
我有一个包含许多输入的注册表单,每个输入的边距为 8dp。它还有一个标题,marginBottom 为 24dp。在某些情况下,有些输入必须隐藏。
所以我希望第一个,无论它是什么,与标题有特定的 24dp 边距,并且彼此之间有 8dp 的边距。
我想用ConstraintLayout解决这个问题。这是我的 xml:
<?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:id="@+id/cho_card_document"
tools:background="#FF0000"
tools:ignore="SpUsage, RtlHardcoded,RtlSymmetry"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="274dp"
android:layout_height="200dp"
android:background="@drawable/cho_shape_round_white_background"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="50dp"
android:id="@+id/cho_ticket_view"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/title"
tools:text="Awesome Title Form"
android:layout_marginTop="24dp"
android:layout_marginLeft="16dp"
app:layout_constraintRight_toRightOf="@+id/cho_ticket_view"
app:layout_constraintLeft_toLeftOf="@+id/cho_ticket_view"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input1"
tools:text="Awesome Input 1"
android:layout_marginTop="24dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/title" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input2"
tools:text="Awesome Input 2"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/input1" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:id="@+id/input3"
tools:text="Awesome Input 3"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/input2" />
</android.support.constraint.ConstraintLayout>
编辑:我已经用实际实现和一些屏幕截图更新了布局。
之前:
隐藏 input1
后,我 input2
离 title
最佳解决方案是将它们放在一个 Contraintlayout 中。然后将该布局限制在标题表单底部所需的边距处。那么当你隐藏input 1时,input 2最多只能向上移动并替换input 1的位置,但不会移动整体布局。希望这有帮助
<RelativeLayout
android:layout_margin="24dp"
android:id="@+id/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/title"
android:text="Awesome Title Form"
/>
</RelativeLayout>
<RelativeLayout
android:layout_margin="8dp"
android:layout_below="@+id/title1"
android:id="@+id/subject"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input1"
android:text="Awesome Input 1"
/>
<TextView
android:layout_below="@+id/input1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input2"
android:text="Awesome Input 2"
/>
<TextView
android:layout_below="@+id/input2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/input3"
android:text="Awesome Input 3"
/>
</RelativeLayout>
你可以通过做两件事来解决这个问题:
- 重新平衡垂直边距的分配方式
- 在您的标题和三个输入视图之间创建垂直 "chain"
重新平衡利润很容易。将 input1
视图上的 android:layout_marginTop="24dp"
更改为使用 8dp
(就像 input2
和 input3
),并将 android:layout_marginBottom="16dp"
添加到 title
视图。这样,无论您输入的哪个视图是 hidden/visible,标题和第一个输入之间的总间距将始终为 24dp。
创建链有点复杂。链中的每个视图都必须同时具有顶部和底部约束。链中的第一个视图应将其顶部约束为 cho_ticket_view
,链中的最后一个视图应将其底部约束为 cho_ticket_view
,其他所有视图(在两个方向上)应约束为它的邻居。
这是它的样子(为简洁起见省略了其他属性):
<TextView
android:id="@+id/title"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view"
app:layout_constraintBottom_toTopOf="@+id/input1"/>
<TextView
android:id="@+id/input1"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input2"/>
<TextView
android:id="@+id/input2"
app:layout_constraintTop_toBottomOf="@+id/input1"
app:layout_constraintBottom_toTopOf="@+id/input3"/>
<TextView
android:id="@+id/input3"
app:layout_constraintTop_toBottomOf="@+id/input2"
app:layout_constraintBottom_toBottomOf="@+id/cho_ticket_view"/>
设置好这八个约束后,这四个视图现在就是一个 "chain"。可以通过向链的 "head" 添加额外的属性来配置链(第一个视图,即 title
给你)。
您将需要 title
视图中的这些属性:
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
使链成为 "packed" 链意味着它将所有额外的 space 放在链外(而不是链中的视图之间)。给它一个 0
的垂直偏差意味着所有额外的 space 都在链的下方(而不是上方)。
这是完整的 XML,结合了上述所有内容:
<?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:id="@+id/cho_card_document"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="#FF0000"
tools:ignore="SpUsage, RtlHardcoded,RtlSymmetry">
<View
android:id="@+id/cho_ticket_view"
android:layout_width="274dp"
android:layout_height="200dp"
android:layout_marginTop="50dp"
android:background="@drawable/cho_shape_round_white_background"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintTop_toTopOf="@+id/cho_ticket_view"
app:layout_constraintLeft_toLeftOf="@+id/cho_ticket_view"
app:layout_constraintRight_toRightOf="@+id/cho_ticket_view"
app:layout_constraintBottom_toTopOf="@+id/input1"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_bias="0"
tools:text="Awesome Title Form"/>
<TextView
android:id="@+id/input1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input2"
tools:text="Awesome Input 1"/>
<TextView
android:id="@+id/input2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/input1"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/input3"
tools:text="Awesome Input 2"/>
<TextView
android:id="@+id/input3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/input2"
app:layout_constraintLeft_toLeftOf="@+id/title"
app:layout_constraintBottom_toBottomOf="@+id/cho_ticket_view"
tools:text="Awesome Input 3"/>
</android.support.constraint.ConstraintLayout>