约束布局中的ScrollView无法滚动到父约束底部

52

我有一个表单,大约有12/13个字段。我在一个约束布局内使用了Scrollview。以下是XML布局的层次结构。问题是,它不会滚动到底部,而只会滚动到前面的10个视图。最后3个字段被隐藏,因为视图无法滚动到更下方。

父布局

<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/activity_register"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">

<!-- Textview and a button -->

  <ScrollView
    android:id="@+id/scrollView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:orientation="vertical"
    android:overScrollMode="never"
    android:scrollbars="none"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/view"
    tools:layout_constraintBottom_creator="1"
    tools:layout_constraintLeft_creator="1"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintTop_creator="1"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="0dp">


  <android.support.constraint.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

                <!-- Child Views (12/13 views of the fields)-->

  </android.support.constraint.ConstraintLayout>

</ScrollView>

</android.support.constraint.ConstraintLayout>

尝试将ScrollViewandroid:layout_height参数更改为match_parent - Ircover
1
尝试过了,但还是不起作用。 - Maheshwari Reddy
你使用的是哪个版本的ConstraintLayout?能否发布完整的XML布局? - Nicolas Roard
嘿,你找到解决方案了吗?我遇到了同样的问题。 - Anudeep
看起来你的约束布局是在滚动视图里面,而不是滚动视图在约束布局里面。 - SMBiggs
显示剩余3条评论
16个回答

120

这个布局在我的应用中起作用。 关键是在ScrollView中设置这两个属性: android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="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"
    android:theme="@style/ThemeOverlay.AppCompat.Light">

    <RelativeLayout
        android:id="@+id/linear"
        android:layout_width="0dp"
        android:layout_height="56dp"
        android:background="@color/title"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/linear">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/titleView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:layout_marginStart="8dp"
                android:text="@string/title"
                android:textSize="14sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/title"
                app:layout_constraintLeft_toLeftOf="parent" />

            <EditText
                android:id="@+id/title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginRight="8dp"
                android:hint="toilet title"
                android:inputType="text"
                android:textColor="@android:color/holo_red_dark"
                android:textSize="12sp"
                app:layout_constraintLeft_toLeftOf="@+id/open_hour"
                app:layout_constraintLeft_toRightOf="@+id/titleView"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
            ...
            Other Views in ScrollView
            ...
        </android.support.constraint.ConstraintLayout>
    </ScrollView>
</android.support.constraint.ConstraintLayout>

2
这个可以工作,但是为什么0dp可以工作而不是wrap_content或match_parent呢? - Jamil
2
在我的情况下,将 app:layout_constraintBottom_toBottomOf="parent" 添加到 ScrollView 中非常有效。我搜索了很多次,直到找到这个解决方案。谢谢。 - Dharmishtha
1
请记住,外部 contraintlayout 通常应该具有 android:layout_width="match_parent"android:layout_height="match_parent"。否则,如果使用 android:layout_height="0dp",则滚动视图将不可见。 - kosiara - Bartosz Kosarzycki
我尝试了很多例子,无论是使用“match_parent”还是“wrap_content”,都不起作用,只有使用“0dp”才有效。 - Chanh

18

在我的情况下,NestedScrollView 能够取代 ScrollView。以下是我正在使用的布局片段:

<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">

    <!-- Some Views Here -->

    <android.support.v4.widget.NestedScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <!-- Some Views That can be Scrolled Here -->

        </android.support.constraint.ConstraintLayout>

    </android.support.v4.widget.NestedScrollView>

</android.support.constraint.ConstraintLayout>

同时在清单文件的Activity中添加android:windowSoftInputMode="stateAlwaysHidden|adjustResize"。 - Jatinder Kumar

16

对于这个问题,您有两种解决方案(相同的解决方案,但有两种不同的方法):

  1. 如果您在Android Studio中打开Design mode,选择ScrollView并打开属性选项卡,在layout_height中选择"match_constraint"。

  2. 如果您在Android Studio中使用Text mode,请使用以下代码:

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tb_details">
    

请注意,ScrollView的高度设置为0dp。这两种方法都解决了同样的问题,但这是不同的做法。

ScrollView不是根视图,我有一个包装ScrollView的Constraint布局,就像你一样。


2
这个方法可行。我有一个ConstraintLayout,其中包含一个ScrollView子元素,它的子元素是一个LinearLayout,可以通过动态添加行来填充。在这个解决方案中的关键是要将高度(滚动轴)设置为0,并且ScrollView必须在滚动轴的两侧进行约束(在这种情况下是顶部和底部约束)。如果您有一个水平滚动视图,您需要将宽度设置为0并设置开始和结束约束。 - Cody

12

两个步骤:

  1. 保持滚动视图的布局高度为零
    android:layout_height="0dp"

  2. 再次针对滚动视图
    android:fillViewport="true"


在我的情况下,高度和宽度都需要是0dp,滚动方向需要是match_parent,否则滚动不起作用。当然,所有4个约束条件都应该添加到RecyclerView中。 - Johnny Five

10

尝试将底部约束添加到滚动视图中(例如:app:layout_constraintBottom_toBottomOf="parent"),并将 android:layout_height="wrap_content" 改为 android:layout_height="0dp"


我忘记给ScrollView加入底部约束。非常感谢 :D - My Will

7
在我的情况下,NestedScrollView 取代了 ScrollView
以下是我工作布局的片段:请确保您没有将任何子视图高度设置为与 constrianlayout 中的父级匹配(0 dp),同时对于滚动视图,请使用android:fillViewport="true"
如有疑问,请询问我。
<android.support.v4.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/_90sdp"
        android:fillViewport="true">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:id="@+id/cvLayout"
            android:animateLayoutChanges="true">

在我的情况下,ScrollView 不起作用,但是 NestedScrollView 可以正常工作。 - Akhil Soni

4

只需在父级布局中添加android:fillViewport="true"即可解决问题。


1
在我的情况下,我有一个高的 TextView(高度设置为 wrap_content )位于一个 ScrollView 内(高度设置为 0dp 并在顶部和底部加以约束)。没有任何建议有效,但是我通过将 TextView 包装在一个 FrameLayout 中(高度设置为 wrap_content)来解决了这个问题。

1

如果ConstraintLayout的子元素位于ScrollView/NestedScrollView内部,请勿将其高度保留为0dp

wrap_content之所以有效,是因为在这种情况下,ScrollView知道其子元素的高度。


这个!!!永远不要使用ConstraintLayout的0DP!!!谢谢。 - Andrew

0
我遇到了另一个问题,其中我有一个嵌套的ScrollView,它包含ConstraintLayout,而该ConstraintLayout又包含一个LinearLayout。该LinearLayout通过编程方式添加子项。因此,滚动无法正常工作。通过将CL替换为具有垂直方向的LL来解决了这个问题。
<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintTop_toBottomOf="@+id/separatr"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:fillViewport="true"
    android:fitsSystemWindows="true"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:orientation="vertical"
        tools:background="@color/yellow_highlight"
        android:paddingBottom="@dimen/box96">


        <TextView
            android:id="@+id/qansTv"
            style="@style/BodyText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/box200"
            android:layout_marginTop="@dimen/box32"
            android:layout_marginEnd="@dimen/box200"
            android:text="Lorem ipsum dofdfd fsd fdfsd sdf sdfsd fsdfsd fd sdfd fsdfsdf sdfsd df sdfd fsdfsd fsdf sdfsd dflors fdfdf."
            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:id="@+id/ansImageContainerLL"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:background="@color/red"
            android:layout_marginEnd="@dimen/box64"
            android:orientation="vertical"
            android:layout_marginStart="@dimen/box64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/qansTv" />

    </LinearLayout>
</androidx.core.widget.NestedScrollView>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接