如何让 ScrollView 填充其父级剩余的 space 的其余部分?
How can I make a ScrollView fill the rest of its parent's remaining space?
我有两个 TextView
和一个 ScrollView
嵌套在 ConstraintLayout
中。在 ScrollView
里面有一个 TableLayout
。 ScrollView 的左、右和底部约束设置为“parent”。顶部约束设置为它之前的 TextView。这是 XML:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:stretchColumns="0,1,2,3,4">
<TableRow
android:layout_width="fill_parent"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="1" />
... 4 more TextViews
</TableRow>
... many more TableRows
</TableLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
问题是 ScrollView 的宽度与其约束不匹配。相反,当添加更多行使得 ScrollView 高于其父级的剩余高度时,它会与它之前的 TextView 重叠。下面两个截图说明了问题:
无重叠:
重叠:
当我将 ScrollView 高度设置为“0dp”(匹配约束)时,它按字面意思呈现为 0dp(ScrollView 缩小并显示其内容的 none)。
我应该更改什么以使 ScrollView 扩展并填充其父容器的剩余高度?
您需要正确约束 ConstraintLayout 的小部件,以便能够正确测量和布置您的视图。
简而言之:
- Top TextView需要是垂直链的头部(
app:layout_constraintVertical_chainStyle="packed"
),并且必须有底部约束(bottom_to_Topof...):
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constrainedHeight="true"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/textView6" />
textView 是 constrainedHeight = true
,因为您希望它 wrap_content
,并且具有文本的小部件在约束布局中包装时可能会出现一些问题(有关更多信息,请参阅 为什么可能需要这样做)。
第二个 TextView 也需要固定到某个底部,在本例中是 scrollView...
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintBottom_toTopOf="@id/scrollView" />
现在它们链接在一起,但 ScrollView 需要一些操作...
只需将滚动视图固定在底部,这样它就可以从某个地方拉动,并给它你需要的 0dp,这样它就可以根据约束计算它的 size/position。
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6">
(也给它一个 name/id...)
这会导致 CL 正确计算 space/sizing 并避免您抱怨的重叠,因为它现在有关于什么可以去哪里的明确规则。
当您省略约束(如 bottom)时,尤其是当周围有像 ScrollViews 这样愚蠢的小部件时,您可能会根据内容产生不可预知的行为,这是很难做到的预期和修复。始终,如有疑问,请尝试为所有小部件提供所有可能的约束。
我会提出几点建议(我不知道哪一个是关键):
1.您不应该对 ConstraintLayout 的子视图使用 match_parent。相反,请使用“0dp”。
Note: You cannot use match_parent for any view in a ConstraintLayout. Instead use "match constraints" (0dp).
2。您不应该使用 @+id/xxx
而是使用 @id/xxx
指定其他视图。 前者用于创建新 ID。
将 ConstraintLayout 的 layout_height 更改为 match_parent
。
将 TableLayout 的 layout_height 更改为 wrap_content
。
我的结果:
layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2" />
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:stretchColumns="0,1,2,3,4">
<TableRow
android:layout_width="fill_parent"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="1" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="2" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="3" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="4" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="5" />
</TableRow>
<!-- plenty of TableRows... -->
</TableLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
我有两个 TextView
和一个 ScrollView
嵌套在 ConstraintLayout
中。在 ScrollView
里面有一个 TableLayout
。 ScrollView 的左、右和底部约束设置为“parent”。顶部约束设置为它之前的 TextView。这是 XML:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:stretchColumns="0,1,2,3,4">
<TableRow
android:layout_width="fill_parent"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="1" />
... 4 more TextViews
</TableRow>
... many more TableRows
</TableLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
问题是 ScrollView 的宽度与其约束不匹配。相反,当添加更多行使得 ScrollView 高于其父级的剩余高度时,它会与它之前的 TextView 重叠。下面两个截图说明了问题:
无重叠:
重叠:
当我将 ScrollView 高度设置为“0dp”(匹配约束)时,它按字面意思呈现为 0dp(ScrollView 缩小并显示其内容的 none)。
我应该更改什么以使 ScrollView 扩展并填充其父容器的剩余高度?
您需要正确约束 ConstraintLayout 的小部件,以便能够正确测量和布置您的视图。
简而言之:
- Top TextView需要是垂直链的头部(
app:layout_constraintVertical_chainStyle="packed"
),并且必须有底部约束(bottom_to_Topof...):
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constrainedHeight="true"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/textView6" />
textView 是 constrainedHeight = true
,因为您希望它 wrap_content
,并且具有文本的小部件在约束布局中包装时可能会出现一些问题(有关更多信息,请参阅
第二个 TextView 也需要固定到某个底部,在本例中是 scrollView...
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintBottom_toTopOf="@id/scrollView" />
现在它们链接在一起,但 ScrollView 需要一些操作...
只需将滚动视图固定在底部,这样它就可以从某个地方拉动,并给它你需要的 0dp,这样它就可以根据约束计算它的 size/position。
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView6">
(也给它一个 name/id...)
这会导致 CL 正确计算 space/sizing 并避免您抱怨的重叠,因为它现在有关于什么可以去哪里的明确规则。
当您省略约束(如 bottom)时,尤其是当周围有像 ScrollViews 这样愚蠢的小部件时,您可能会根据内容产生不可预知的行为,这是很难做到的预期和修复。始终,如有疑问,请尝试为所有小部件提供所有可能的约束。
我会提出几点建议(我不知道哪一个是关键):
1.您不应该对 ConstraintLayout 的子视图使用 match_parent。相反,请使用“0dp”。
Note: You cannot use match_parent for any view in a ConstraintLayout. Instead use "match constraints" (0dp).
2。您不应该使用 @+id/xxx
而是使用 @id/xxx
指定其他视图。 前者用于创建新 ID。
将 ConstraintLayout 的 layout_height 更改为
match_parent
。将 TableLayout 的 layout_height 更改为
wrap_content
。
我的结果:
layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView2" />
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView6">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
android:gravity="center"
android:stretchColumns="0,1,2,3,4">
<TableRow
android:layout_width="fill_parent"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="1" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="2" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="3" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="4" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="5" />
</TableRow>
<!-- plenty of TableRows... -->
</TableLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>