Android - як зробити прокручуваний обмежувальний проміжок?


150

Я хочу зробити макет, який дозволяє мені прокручуватися вниз за допомогою макета обмеження, але я не знаю, як це робити. Чи повинен ScrollViewбути батьком ConstraintLayoutподібного?

<?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="match_parent"
    android:fillViewport="true">

<android.support.constraint.ConstraintLayout
    android:id="@+id/Constraint"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Або навпаки? Можливо, хтось може вказати мені на гарний підручник з цього питання або навести приклад, я, здається, не можу його знайти.

Крім того, я не знаю, чи це помилка чи якась конфігурація, яку я не встановив, але я бачив такі зображення:

введіть тут опис зображення

де є деякі компоненти поза планом «синього прямокутника», але вони видні, тоді як на моєму боці, якщо я розміщую компонент на «білому просторі», я його не бачу і не переміщую куди завгодно, і він з’являється на дереві компонентів .

ОНОВЛЕННЯ:

Я знайшов спосіб зробити макет обмеження прокручуватися в інструменті проектування, використовуючи горизонтальну орієнтир, щоб відсунути межу макета обмеження і витягнути його за межі пристрою, після чого ви можете використовувати орієнтир як нову нижню частину макета обмеження для закріплюють компоненти.

Відповіді:


85

Здається, що це працює, я не знаю, з якою залежністю ви працювали, але в цій

compile 'com.android.support.constraint:constraint-layout:1.0.2'

Працює, це я і зробив

<?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="match_parent"
    tools:context=".MainActivity">

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

        <android.support.design.widget.TextInputLayout
            android:id="@+id/til_input"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="Escriba el contenido del archivo"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@+id/btn_save"
            app:layout_constraintTop_toTopOf="@id/btn_save"
            app:layout_constraintVertical_chainStyle="spread">

            <EditText
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </android.support.design.widget.TextInputLayout>

        <Button
            android:id="@+id/btn_save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClickButtonSave"
            android:text="Guardar"
            app:layout_constraintLeft_toRightOf="@+id/til_input"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/txt_content"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/til_input"
            app:layout_constraintVertical_chainStyle="spread"
            app:layout_constraintVertical_weight="1" />

        <Button
            android:id="@+id/btn_delete"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:onClick="onClickButtonDelete"
            android:text="Eliminar"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/txt_content"
            app:layout_constraintVertical_chainStyle="spread" />

    </android.support.constraint.ConstraintLayout>

</ScrollView>

Прокручування вгорувведіть тут опис зображення

Прокрутіть знизувведіть тут опис зображення


3
спасибі, проблема полягала в тому, що я не міг прокручувати попередній перегляд, тому створення чогось там було неможливим, але я виявив, що за допомогою настанови я можу
зрушити

2
ця відповідь повинна бути зверху!
Костанос

60

Існує тип обмеження, яке порушує функцію прокрутки:

Просто переконайтеся, що ви не користуєтесь цим обмеженням для будь-якого виду, бажаючи, ConstraintLayoutщоб ваш файл можна прокручувати за допомогою ScrollView:

app:layout_constraintBottom_toBottomOf=“parent

Якщо ви вилучите ці, ваш прокрутка повинна спрацювати.

Пояснення:

Визначення висоти дитини відповідно до висоти ScrollViewбатьків суперечить тому, що призначений для виконання компонент. Що ми хочемо більшу частину часу, це вміст динамічного розміру, який можна прокручувати, коли він більше екрана / кадру; узгодження висоти з батьківським ScrollViewзмушує весь вміст відображатися у фіксованому кадрі (висота батьківського), отже, вимкнення будь-якої функції прокрутки.

Це також відбувається, коли встановлені звичайні дочірні компоненти layout_height="match_parent".

Якщо ви хочете, щоб дитина дитини ScrollViewвідповідала зростанню батьків, коли вмісту недостатньо, просто встановіть android:fillViewportзначення true для ScrollView.


1
@BasilBattikhi Додав пояснення
SuppressWarnings

3
Блін це насправді спрацювало! Я ненавиджу погляди прокрутки, серйозно.
Удай

2
Дякую @SuppressWarnings, дуже ціную це. Ви натякаєте на видалення програми "layout: layout_constraintBottom_toBottomOf =" батьків "" 100%
Jignesh

1
+1, дійсно корисний, не знав, чому предмети в моєму прокрутку не розташовуються на потрібному місці.
Хесус Хагівара

1
Так правильно ... але для досягнення тієї ж вимоги дотримуйтесь підходу, про який я згадував вище.
Рагхав Шарма

28

Використовувати 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>

для android x використовуйте це

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

</androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.core.widget.NestedScrollView>

4
Дякую! Це те, що я шукав - ключовим є android: fillViewport = "true".
Пратт

не забудьте додати всередину nestedscrollview, якщо ви використовуєте AppBarLayoutapp:layout_behavior="@string/appbar_scrolling_view_behavior"
majurageerthan

1
На сьогоднішній день це правильна відповідь!
madfree

11

Підводячи підсумок, ви в основному android.support.constraint.ConstraintLayoutпереглядаєте свій перегляд у ScrollViewтексті *.xmlфайлу, пов’язаному з вашим макетом.

Приклад Activity_sign_in.xml

<?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="match_parent"
    tools:context=".SignInActivity"> <!-- usually the name of the Java file associated with this activity -->

    <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:background="@drawable/gradient"
        tools:context="app.android.SignInActivity">

        <!-- all the layout details of your page -->

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

Примітка 1: Панелі прокрутки з’являються лише в тому випадку, якщо потрібна обмотка будь-яким способом, включаючи спливаючу клавіатуру.

Примітка 2: Також не було б поганою ідеєю, щоб переконатися, що ваш ConstraintLayout є достатньо великим, щоб досягти нижньої та бічної сторін будь-якого екрана, особливо якщо у вас є фон, оскільки це забезпечить відсутність незвичайного пробілу . Ви можете зробити це з пробілами, якщо нічого іншого.


9

Просто використовуйте макет обмежень всередині NestedScrollViewабо ScrollView.

<android.support.v4.widget.NestedScrollView
        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.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white">

 </android.support.constraint.ConstraintLayout>

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

Це воно. насолоджуйтесь кодуванням.


4

Щоб зробити макет, який можна прокручувати, макет правильний. Він не буде прокручуватися, доки не буде підстав для прокрутки (як у будь-якому іншому макеті). Тому додайте достатньо вмісту, і він буде прокручуватися, як і будь-який макет (лінійний, відносний тощо). Однак ви не можете прокручувати належним чином у програмі Blueprint або дизайні під час проектування за допомогою ConstraintLayout та ScrollView.

Значення:

Ви можете зробити прокручуваний ConstraintLayout, але він не буде прокручуватися належним чином у редакторі через помилку / сценарій, який не враховувався. Але хоча прокрутка не працює в редакторі, вона працює на пристроях. (Я зробив декілька прокручувальних макетів COnstraint, тому я перевірив це)

Примітка

Щодо вашого коду. У ScrollView відсутній закриваючий тег, я не знаю, чи це так у файлі чи це пропуск копію-вставки, але ви можете поглянути на нього.


1
Щоб спроектувати прокручувану обмежувальну версію, у поточному стані CL, тобто, можна розширити висоту пристрою та зробити його на замовлення. Встановіть висоту макетів (ScrollView і CL) на високе число (наприклад, 2000DP) і просто виконайте звичайне проектування. Зауважте, що вам потрібен хороший комп'ютер для управління розширенням, оскільки дійсно великі спеціальні пристрої вимагають багато від комп'ютера. Прикро, що CL не підтримує розробку за допомогою SCrollViews, але є обхідні шляхи. наприклад, розширення висоти пристрою.
Зої

3

Для завершення попередніх відповідей додаю наступний приклад, який також враховує використання AppBar. З цим кодом, здається, редактор дизайну Android Studio добре працює з ConstraintLayout.

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout
    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:fitsSystemWindows="true"
    android:background="@drawable/bg"
    android:orientation="vertical">

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.ActionBar.AppOverlayTheme">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

        <ImageView
            android:id="@+id/image_id"
            android:layout_width="match_parent"
            android:layout_height="@dimen/app_bar_height"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            android:src="@drawable/intro"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent" />

        <TextView
            android:id="@+id/desc_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/text_margin"
            android:text="@string/intro_desc"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/image_id" />

        <Button
            android:id="@+id/button_scan"
            style="?android:textAppearanceSmall"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="@color/colorAccent"
            android:padding="8dp"
            android:text="@string/intro_button_scan"
            android:textStyle="bold"
            app:layout_constraintTop_toBottomOf="@+id/desc_id" />

        <Button
            android:id="@+id/button_return"
            style="?android:textAppearanceSmall"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:backgroundTint="@color/colorAccent"
            android:padding="8dp"
            android:text="@string/intro_button_return"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/button_recycle" />

        <Button
            android:id="@+id/button_recycle"
            style="?android:textAppearanceSmall"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="@color/colorAccent"
            android:padding="8dp"
            android:text="@string/intro_button_recycle"
            android:textStyle="bold"
            app:layout_constraintTop_toBottomOf="@+id/button_scan" />
    </android.support.constraint.ConstraintLayout>
</ScrollView>
</LinearLayout>

2

вам потрібно оточити мій обмеження-макет тегом ScrollView і надав йому властивість android: isScrollContainer = "вірно".


1

Існує помилка у версії 2.2, яка унеможливлює прокрутку ConstraintLayout. Я здогадуюсь, це все ще існує. Можна альтернативно використовувати LinearLayout або RelativeLayout.

Також перевірте: чи можна поставити макет обмеження всередині ScrollView .


Запропонуйте використовувати натомість RelativeLayout, він найближчий до ConstraintLayout
Zoe

Виправлено помилку.
X09

1

Constraintlayout - це за замовчуванням для нового додатка. Зараз я "навчаюся на Android" і мені дуже важко було зрозуміти, як обробляти типовий "зразок" коду для прокрутки, коли клавіатура працює. Я бачив багато програм, де мені доводиться закривати клавіатуру, щоб натиснути кнопку «подати», а іноді вона не проходить. Використовуючи цю ієрархію [ScrollView / ContraintLayout / Fields], вона зараз працює чудово. Таким чином, ми можемо отримати переваги та простоту використання від ConstraintLayout у вигляді прокрутки.


1

Вийміть нижню кнопку з вкладеного перегляду та візьміть лінійний розміт як батьківський. Додайте донизу та вкладеного перегляду як своїх дітей. Це буде працювати нормально. У маніфесті для діяльності використовуйте це - це підніме кнопку, коли клавіатура відкриється

android:windowSoftInputMode="adjustResize|stateVisible"

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:orientation="vertical">

    <androidx.core.widget.NestedScrollView xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/input_city_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="20dp"
                android:layout_marginTop="32dp"
                android:layout_marginEnd="20dp"
                android:hint="@string/city_name"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/city_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:digits="abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    android:lines="1"
                    android:maxLength="100"
                    android:textSize="16sp" />

            </com.google.android.material.textfield.TextInputLayout>

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.core.widget.NestedScrollView>

    <Button
        android:id="@+id/submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:onClick="onSubmit"
        android:padding="12dp"
        android:text="@string/string_continue"
        android:textColor="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="parent" />

</LinearLayout>


0

Ось як я це вирішив:
Якщо ви використовуєте вкладений ScrollView, тобто ScrollView в ConstraintLayout, використовуйте наступну конфігурацію для ScrollView замість "WRAP_CONTENT" або "MATCH_PARENT":


<ScrollView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/someOtherWidget"
    app:layout_constraintTop_toTopOf="parent">

0

в scrollview зробіть висоту і ширину 0 додайте обмеження Top_toBottomOfand Bottom_toTopOf.


Будь ласка, поясніть цю відповідь докладніше, наприклад, приклад коду для реалізації.
Джейк

0

Для мене, здається, жодна пропозиція щодо видалення обмежень на дні та встановлення контейнера прокрутки не відповідає дійсності. Що працювало: розширюйте висоту окремих / вкладених представлень у моєму макеті, щоб вони "перекинулися" за межами батьківського, використовуючи параметр "Розгорнути вертикально" Редактора макетів обмежень, як показано нижче.

Для будь-якого підходу важливо, щоб пунктирні лінії попереднього перегляду простягалися вертикально за межами батьківського верхнього або нижнього розмірів

Розгорніть вертикально

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.