Можно ли поместить ConstraintLayout в ScrollView?

Так недавно в Android Studio 2.2 появился новый ConstraintLayout, который значительно упрощает проектирование, но в отличие от RelativeLayout и Linearlayout, я не могу использовать ScrollView для окружения ConstraintLayout. Это возможно? Если да, то как?

i.e.

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

person Seth Painter    schedule 20.05.2016    source источник
comment
Что вам мешает это сделать? Вы всегда можете просто добавить его напрямую в XML ...   -  person Karakuri    schedule 20.05.2016
comment
Вы должны добавить код и любую полученную ошибку.   -  person Alok    schedule 20.05.2016
comment
Если я использую layout_height="wrap_content", приложение показывает пустой экран, но если я использую layout_height="match_parent", приложение не прокручивается.   -  person Seth Painter    schedule 20.05.2016
comment
По-видимому, при установке layout_height в wrap_content ConstraintLayout каким-то образом игнорирует его дочерние элементы и сворачивается. Это так, даже если дочерние элементы имеют определенные ограничения относительно верха и низа ConstraintLayout (например, полей).   -  person Jakub Mendyk    schedule 22.05.2016
comment
Можно ли что-нибудь сделать, чтобы прокручивать макет ограничения, или мне следует вернуться и использовать другой макет?   -  person Seth Painter    schedule 22.05.2016
comment
У меня такая же проблема, но вместо того, чтобы сворачиваться, она просто игнорируется при переходе в многооконный режим. Если это вас задерживает, возможно, вам стоит сейчас найти другой макет. Если что-нибудь придумываю, отвечу.   -  person DR Haus    schedule 23.05.2016
comment
Похоже, Google исправил ошибку. Теперь вы можете использовать ConstraintLayout внутри scrollviews и reyclerviews в Android Studio 2.2 Preview 2 (constraintlayout 1.0.0-alpha2). См. tools.android.com/recent/androidstudio22preview2available   -  person ekcr1    schedule 29.05.2016


Ответы (12)


Ошибка с ConstraintLayout внутри ScrollViews была исправлена. Google исправил ошибку в Android Studio 2.2 Preview 2 (constraintlayout 1.0.0-alpha2).

Проверьте эту ссылку на наличие нового обновления (предварительная версия 2): правильно работает в ScrollView и RecycleView

Решение 1:

Решением было использовать android:fillViewport="true" на ScrollView

Решение 2:

Используйте NestedScrollView вместо ScrollView с android:fillViewport="true"

Изменить - 16.09.20:

В настоящее время более обычным является использование ScrollView с высотой ConstraintLayout, установленной на wrap_content, он работает очень хорошо, не забывайте о fillViewPort и о том, что как Scroll, так и Nested поддерживают только одного прямого дочернего элемента.

person Govinda Paliwal    schedule 31.05.2016
comment
Похоже, они этого не исправили. Это все еще не работает в производственной версии - person SimonH; 26.09.2016
comment
Могу подтвердить. Не исправлено даже в 2.3.3. - person Muhammad Babar; 23.06.2017
comment
Решение см. Ниже. - person eric.mcgregor; 06.12.2017
comment
Добавление android: fillViewport = true в ScrollView сработало. Android Studio 4.0.1 - person Rupam Das; 19.07.2020

Попробуйте добавить android:fillViewport="true" в ScrollView.

Нашел решение здесь: LinearLayout не расширяется внутри ScrollView

person eric.mcgregor    schedule 12.03.2017
comment
да, у меня эта работа отлично работает, спасибо @ eric.mcgregor - person Harin Kaklotar; 24.06.2017
comment
ты спас мне жизнь! - person faraz khonsari; 11.07.2017
comment
Работает даже в Android Studio 3.0 !! - person learn2code; 19.04.2018
comment
Идет мой герой - person Paul Alexander; 11.08.2018
comment
Спаси мой день! Это должно быть изменено на принятый ответ - person Pham; 04.10.2019
comment
Идеально для меня, Thnaks !! - person Shadros; 09.06.2020

использовать NestedScrollView с окном просмотра 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>
person Rajesh Wolf    schedule 18.12.2017
comment
Вы, сэр, спасли мне день. Это должен быть принятый ответ. - person Євген Гарастович; 21.12.2018
comment
почему вы указали жестко заданную высоту макета? Разве это невозможно для match_parent или wrap_content? - person Kumararaja; 18.02.2021

Не забывайте, что если вы ограничиваете нижнюю часть некоторого представления до низа макета, Scrollview не может прокручиваться.

person ahmetvefa53    schedule 26.03.2019
comment
На самом деле я несколько столкнулся с этой проблемой: я ограничил нижнюю часть последнего представления некоторым значением, но Constaintlayout не может прокручиваться за пределы последнего элемента - person Claude Hangui; 11.04.2019
comment
В этом случае удалите нижнее ограничение и программно установите minHeight. По крайней мере, сработал для моего варианта использования - person Ultimo_m; 29.04.2021

Установите 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>
person Sakib Syed    schedule 15.05.2017
comment
Почему ConstraintLayout находится внутри и вне ScrollView? Должен ли ScrollView быть корневым элементом с ConstraintLayout внутри? - person Diego Malone; 29.12.2017

Попробуйте добавить нижний отступ к макету ограничений, как показано ниже.

    <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>
person DragonFire    schedule 01.01.2020

Любой, кто установил свойство ниже

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>
person Muhammad Maqsood    schedule 25.08.2020
comment
Проблема для меня была app:layout_constraintBottom_toBottomOf="parent". Поэтому, если вы хотите что-то центрировать, используйте app:layout_constraintBottom_toTopOf="parent" и app:layout_constraintTop_toBottomOf="parent" - person ravi; 23.02.2021

Поскольку фактический ScrollView инкапсулирован в CoordinatorLayout с Toolbar ...

<?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" мне не нужно.

person JJD    schedule 16.04.2018

Я потратил 2 дня, пытаясь преобразовать макеты в ConstraintLayout в так называемой «стабильной» версии Android Studio 2.2, и у меня нет ScrollView для работы в дизайнере. Я не собираюсь начинать процесс добавления ограничений в XML для Views, которые находятся дальше по прокрутке. В конце концов, это должен быть инструмент визуального дизайна.

И количество ошибок рендеринга, переполнения стека и проблем с темами, которые у меня были, привело меня к выводу, что вся реализация ConstraintLayout все еще пронизана ошибками. Если вы не разрабатываете простые макеты, я бы оставил это в покое, пока не будет хотя бы еще несколько итераций.

Вот 2 дня назад не вернусь.

person SimonH    schedule 23.09.2016
comment
Становится лучше, убедитесь, что вы используете последнюю версию, которая сейчас 1.0.0-alpha9 и File- ›Invalidate Caches / Restart. - person goetzc; 02.10.2016
comment
Спасибо. Это улучшение. И это уменьшило количество ошибок рендеринга. Но я все еще не уверен, что он достаточно стабилен, чтобы попробовать конвертировать все мои макеты. Я решил подождать, пока они полностью избавятся от тега 'alpha' и выпустят надлежащую производственную версию - person SimonH; 06.10.2016

У меня был NestedScrollView внутри ConstraintLayout, а этот NestedScrollView имеет один ConstraintLayout.

Если вы столкнулись с проблемой с NestedScrollView,

добавить android:fillViewport="true" в NestedScrollView, сработало.

person AskQ    schedule 12.02.2021

ПРОБЛЕМА:

У меня возникла проблема с ConstraintLayout и ScrollView, когда я хотел включить его в другой макет.

РЕШЕНИЕ:

Решением моей проблемы было использование привязки данных.

привязка данных (макет)

person Владислав Шестернин    schedule 04.12.2020

Не забывайте про свойство tools:context=".YouClassName" в ScrollView.

Это то, что вызывало сбой моего приложения.

person Dmitry    schedule 11.03.2019