是否可以将 ConstraintLayout 放在 ScrollView 中?

Is it possible to put a ConstraintLayout inside a ScrollView?

最近,Android Studio 2.2 有一个新的 ConstraintLayout,它使设计变得容易得多,但与 RelativeLayoutLinearlayout 不同,我不能使用 ScrollView 包围 ConstraintLayout。这可能吗?如果是,怎么做?

<ScrollView 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: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="match_parent"
            tools:layout_editor_absoluteX="0dp"
            tools:layout_editor_absoluteY="0dp">
            
            <!-- Have whatever children you want inside -->
            
        </android.support.constraint.ConstraintLayout>
        
</ScrollView>

ScrollView 中的 ConstraintLayout 存在错误,该错误已修复。 google 已修复 Android Studio 2.2 Preview 2 (constraintlayout 1.0.0-alpha2) 中的错误。

检查此 link 是否有新更新(预览版 2):works properly inside ScrollView and RecycleView

解决方案 1:

The solution was to use android:fillViewport="true" on the ScrollView

解决方案 2:

Use NestedScrollView instead of ScrollView with android:fillViewport="true"

编辑 - 20 年 9 月 16 日:

目前比较常用的是ScrollView,ConstraintLayout高度设置为wrap_content,效果很好,别忘了fillViewPort,Scroll和Nested都只支持一个direct child。

我花了 2 天时间尝试将布局转换为 ConstraintLayout 在所谓的 "stable" 版本 Android Studio 2.2 中,但我没有 ScrollView在设计师工作。我不打算开始在 XML 中为 Views 添加约束的路线,这些约束在滚动条的下方。毕竟这应该是一个视觉设计工具。

我遇到的渲染错误、堆栈溢出和主题问题的数量让我得出结论,整个 ConstraintLayout 实施仍然充满错误。除非你正在开发简单的布局,否则我会把它放在一边,直到它至少有几次迭代。

那是我回不来的 2 天。

尝试将 android:fillViewport="true" 添加到 ScrollView。

在此处找到解决方案:LinearLayout not expanding inside a ScrollView

ScrollView layout_height 设置为 wrap_content 然后它将正常工作。以下是可能对某人有所帮助的示例。 我使用 compile 'com.android.support.constraint:constraint-layout:1.0.2' 进行约束布局。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:orientation="vertical"
    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:id="@+id/activity_main"
    tools:context=".ScrollViewActivity">

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        >

        <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="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:scrollbars="vertical">

            <TextView
                android:id="@+id/tvCommonSurname"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="surname"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="text"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonSurname"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/tvCommonName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="firstName"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText3"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="text"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonName"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/tvCommonLastName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="middleName"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="text"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonLastName"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/tvCommonPhone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="Phone number"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText2"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText4"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:digits="0123456789"
                android:ems="10"
                android:inputType="phone"
                android:maxLength="10"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonPhone"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="sex"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText4"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <RadioGroup 
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/radiogroup"
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_marginTop="8dp"
                android:orientation="horizontal"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView3"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1">

                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="pirates" />

                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="ninjas" />
            </RadioGroup>

            <TextView
                android:id="@+id/tvCommonDOB"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="dob"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/radiogroup"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText5"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="date"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonDOB"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/tvCommonLivingCity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="livingCity"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText5"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText34"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="text"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonLivingCity"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/tvCommonPlaceOfBithday"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="placeOfBirth"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText34"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <EditText
                android:id="@+id/editText6"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:ems="10"
                android:inputType="text"
                android:maxLines="1"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tvCommonPlaceOfBithday"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

            <TextView
                android:id="@+id/textView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:text="education"
                android:textAppearance="?android:attr/textAppearanceLarge"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/editText6"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintTop_creator="1" />

            <Spinner
                android:id="@+id/spinner_id"
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_marginTop="8dp"
                android:spinnerMode="dialog"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView4"
                tools:layout_constraintLeft_creator="1"
                tools:layout_constraintRight_creator="1"
                tools:layout_constraintTop_creator="1" />

        </android.support.constraint.ConstraintLayout>
    </ScrollView>


</android.support.constraint.ConstraintLayout>

使用 NestedScrollView with viewport true 对我来说效果很好

<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

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

        </android.support.constraint.ConstraintLayout>

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

因为实际的 ScrollView 封装在 CoordinatorLayoutToolbar ...

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/list"/>

</android.support.design.widget.CoordinatorLayout>

...我必须定义 android:layout_marginTop="?attr/actionBarSize" 才能使滚动工作:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    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="wrap_content"
    android:layout_marginTop="?attr/actionBarSize">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- UI elements here -->

    </android.support.constraint.ConstraintLayout>

</ScrollView>

以上也适用于 NestedScrollView 而不是 ScrollView。 我不需要定义 android:fillViewport="true"

不要忘记 tools:context=".YouClassName" 属性 在 ScrollView.

这就是导致我的应用程序崩溃的原因。

不要忘记,如果将某些视图的底部约束为约束布局的 bottom.Scrollview 则无法滚动。

尝试为您的约束布局提供一些填充底部,如下所示

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/top"
        android:fillViewport="true">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="100dp">
        </android.support.constraint.ConstraintLayout>

    </ScrollView>

属性以下设置为

的任何人

滚动视图:android:fillViewport="true"

约束布局: android:layout_height="wrap_content"

它仍然无法正常工作,然后确保您没有将内部可滚动布局 (RecycleView) 底部约束设置为父级底部。

添加以下代码行:

android:nestedScrollingEnabled="false"
android:layout_height="wrap_content"

确保删除以下约束:

app:layout_constraintBottom_toBottomOf="parent"

完整代码

   <androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/selectHubLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".ui.hubs.SelectHubFragment">

    <include
        android:id="@+id/include"
        layout="@layout/signup_hub_selection_details"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_HubSelection"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:nestedScrollingEnabled="false"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/include" />
</androidx.constraintlayout.widget.ConstraintLayout>

问题:

我想在另一个布局中 包含 ConstraintLayout 和 ScrollView 时遇到问题。

决定:

我的问题的解决方案是使用 dataBinding。

dataBinding (layout)

我在 ConstraintLayout 中有 NestedScrollView,而这个 NestedScrollView 有一个 ConstraintLayout

如果您遇到 NestedScrollView

的问题

android:fillViewport="true" 添加到 NestedScrollView,成功了。

NestedScrollViewandroid:fillViewport="true"

结合使用
<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

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

        <!--Edit your stuff-->

    </android.support.constraint.ConstraintLayout>

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