Android - bagaimana cara membuat pembatas scrollable?

149

Saya ingin membuat tata letak yang memungkinkan saya gulir ke bawah menggunakan tata letak kendala, tapi saya tidak tahu bagaimana cara melakukannya. Haruskah ScrollViewmenjadi orang tua ConstraintLayoutseperti ini?

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

Atau sebaliknya? Mungkin seseorang dapat mengarahkan saya ke tutorial yang bagus tentang hal ini atau memberikan contoh, sepertinya saya tidak dapat menemukannya.

Juga, saya tidak tahu apakah ini bug atau konfigurasi yang belum saya atur tetapi saya telah melihat gambar seperti ini:

masukkan deskripsi gambar di sini

di mana ada beberapa komponen di luar cetak biru "persegi panjang biru" namun mereka terlihat, sementara di sisi saya jika saya menempatkan komponen pada "ruang putih" Saya tidak bisa melihatnya atau memindahkannya ke mana saja, dan itu muncul di pohon komponen .

PEMBARUAN:

Saya menemukan cara untuk membuat tata letak kendala digulir dalam alat desain, menggunakan pedoman horizontal untuk menekan batas tata letak kendala dan memperluasnya di luar perangkat, setelah itu, Anda dapat menggunakan pedoman sebagai bagian baru dari tata letak kendala untuk jangkar komponen.

gtovar
sumber

Jawaban:

84

Tampaknya itu berfungsi, saya tidak tahu ketergantungan apa yang sedang Anda kerjakan tetapi dalam hal ini

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

Bekerja, ini yang saya lakukan

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

Gulir ke Atasmasukkan deskripsi gambar di sini

Gulir ke Bawahmasukkan deskripsi gambar di sini

sealroto
sumber
3
terima kasih, masalahnya adalah bahwa saya tidak dapat menggulir pada pratinjau, jadi membangun sesuatu di sana tidak mungkin tetapi saya menemukan bahwa dengan menggunakan pedoman saya dapat menarik ke bawah tata letak untuk membuat ruang kosong yang dapat digulir dan kemudian menghapusnya ketika saya selesai
gtovar
1
jawaban ini harus ada di atas!
Kostanos
60

Ada jenis kendala yang merusak fungsi gulir:

Pastikan Anda tidak menggunakan batasan ini pada tampilan apa pun saat ingin Anda ConstraintLayoutdapat digulir dengan ScrollView:

app:layout_constraintBottom_toBottomOf=“parent

Jika Anda menghapus ini, gulir Anda akan berfungsi.

Penjelasan:

Mengatur tinggi anak agar sesuai dengan ScrollVieworang tua bertentangan dengan apa yang harus dilakukan komponen. Yang kami inginkan sebagian besar waktu adalah untuk beberapa konten berukuran dinamis untuk dapat digulir ketika itu lebih besar dari layar / bingkai; mencocokkan tinggi dengan induknyaScrollView akan memaksa semua konten untuk ditampilkan ke dalam bingkai tetap (ketinggian induk) sehingga membatalkan fungsi gulir.

Ini juga terjadi ketika komponen anak langsung langsung diatur ke layout_height="match_parent" .

Jika Anda ingin anak dari ScrollViewmencocokkan ketinggian orangtua ketika tidak ada cukup konten, cukup setel android:fillViewportke true untuk ScrollView.

SuppressWarnings
sumber
1
@BasilBattikhi Menambahkan penjelasan
SuppressWarnings
3
Sialan ini benar-benar berhasil! Aku benci tampilan gulir, serius.
Uday
2
Terima kasih @SuppressWarnings, sangat menghargainya. Anda bisa menghapus "app: layout_constraintBottom_toBottomOf =" parent "" bekerja 100%
Jignesh
1
+1, sangat berguna, tidak tahu mengapa item di dalam scrollview saya tidak diposisikan di tempat yang saya inginkan.
Jesús Hagiwara
1
Ya benar ... tetapi untuk mencapai persyaratan yang sama, ikuti pendekatan yang telah saya sebutkan di atas.
Raghav Sharma
28

Gunakan NestedScrollView dengan viewport true berfungsi baik untuk saya

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

untuk android x gunakan ini

 <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>
Abhay Pratap
sumber
4
Terima kasih! Inilah yang saya cari - android: fillViewport = "true" adalah kuncinya.
pratt
jangan lupa untuk menambahkan nestedscrollview di dalam, jika Anda menggunakan AppBarLayoutapp:layout_behavior="@string/appbar_scrolling_view_behavior"
majurageerthan
1
Sampai saat ini, ini adalah jawaban yang benar!
madfree
11

Untuk meringkas, pada dasarnya Anda membungkus android.support.constraint.ConstraintLayouttampilan Anda di ScrollViewdalam teks *.xmlfile yang terkait dengan tata letak Anda.

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

Catatan 1: Bilah gulir hanya muncul jika bungkus diperlukan dengan cara apa pun, termasuk keyboard yang muncul.

Catatan 2: Ini juga bukan ide yang buruk untuk memastikan ConstraintLayout Anda cukup besar untuk mencapai bagian bawah dan samping layar tertentu, terutama jika Anda memiliki latar belakang, karena ini akan memastikan bahwa tidak ada ruang kosong yang aneh . Anda dapat melakukan ini dengan spasi jika tidak ada yang lain.

StackAttack
sumber
9

Cukup gunakan tata letak kendala di dalam NestedScrollViewatau 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>

itu dia. nikmati pengkodean Anda.

mahendren
sumber
4

Untuk membuat tata letak yang dapat digulir, tata letaknya benar. Ini tidak akan dapat digulir sampai ada alasan untuk menggulir (seperti pada tata letak lainnya). Jadi, tambahkan cukup konten dan itu akan dapat digulir, seperti halnya dengan tata letak apa pun (Linear, Relatif, dll). Namun, Anda tidak dapat menggulir dengan benar dalam Cetak Biru atau mode desain desain saat merancang dengan ConstraintLayout dan ScrollView.

Berarti:

Anda dapat membuat ConstraintLayout yang dapat digulir, tetapi itu tidak akan menggulir dengan benar di editor karena bug / skenario yang tidak dipertimbangkan. Tetapi meskipun bergulir tidak bekerja di editor, itu bekerja pada perangkat. (Saya telah membuat beberapa bergulir COnstraintLayouts, jadi saya telah mengujinya)

Catatan

Mengenai kode Anda. ScrollView tidak memiliki tag penutup, saya tidak tahu apakah itu yang terjadi pada file atau jika ini merupakan miss-paste-rindu, tetapi Anda mungkin ingin melihatnya.

Zoe
sumber
1
Untuk merancang pembatas kendala yang dapat digulir, dalam kondisi CL saat ini, Anda dapat memperluas ketinggian perangkat dan membuatnya khusus. Atur ketinggian tata letak (ScrollView dan CL) ke angka tinggi (mis. 2000DP) dan lakukan saja perancangan normal. Perhatikan bahwa Anda memerlukan komputer yang bagus untuk menangani ekspansi, karena perangkat kustom yang sangat besar membutuhkan banyak dari komputer. Sayang CL tidak mendukung desain dengan SCrollViews, tetapi ada beberapa solusi. seperti memperluas ketinggian perangkat.
Zoe
3

Untuk melengkapi jawaban sebelumnya saya menambahkan contoh berikut, yang juga memperhitungkan penggunaan AppBar. Dengan kode ini, editor desain Android Studio tampaknya berfungsi baik dengan 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>
narko
sumber
2

Anda perlu dikelilingi tata letak kendala saya dengan tag ScrollView dan memberikannya properti android: isScrollContainer = "true".

Sam
sumber
1

Ada bug di versi 2.2 yang membuatnya tidak mungkin untuk menggulir ConstraintLayout. Saya kira itu masih ada. Anda dapat menggunakan LinearLayout atau RelativeLayout sebagai alternatif.

Juga, periksa: Apakah mungkin untuk menempatkan tata letak kendala di dalam ScrollView .

Ege Kuzubasioglu
sumber
Sarankan menggunakan RelativeLayout sebagai gantinya, ini adalah yang terdekat dengan ConstraintLayout
Zoe
Bug telah diperbaiki.
X09
1

Constraintlayout adalah Default untuk aplikasi baru. Saya "belajar untuk Android" sekarang dan memiliki waktu yang sangat sulit mencari tahu bagaimana menangani kode "sampel" default untuk menggulir ketika keyboard menyala. Saya telah melihat banyak aplikasi di mana saya harus menutup keyboard untuk mengklik tombol "kirim" dan kadang-kadang tidak hilang. Menggunakan hierarki [ScrollView / ContraintLayout / Fields] ini berfungsi dengan baik sekarang. Dengan cara ini kita dapat memperoleh manfaat dan kemudahan penggunaan dari ConstraintLayout dalam tampilan yang dapat digulir.

Renato Bourdon
sumber
1

Keluarkan tombol bawah dari nestedscrollview dan ambil linearlayout sebagai orangtua. Tambahkan bawah dan nestedscrollview sebagai anak-anak mereka. Ini akan bekerja dengan sangat baik. Manifes untuk aktivitas gunakan ini - ini akan menaikkan tombol ketika keyboard dibuka

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>
Raghav Sharma
sumber
0

Anda dapat menggunakan HorizontalScrollViewdan itu akan berhasil juga!

Morgan Koh
sumber
Tolong jelaskan bagaimana cara menggunakannya
FindOutIslamNow
0

Inilah cara saya mengatasinya:
Jika Anda menggunakan Nested ScrollView, yaitu ScrollView di dalam ConstraintLayout, gunakan konfigurasi berikut untuk ScrollView alih-alih "WRAP_CONTENT" atau "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">
Sajid2405
sumber
0

di scrollview, buat tinggi dan lebar 0 tambahkan kendala Top_toBottomOfand Bottom_toTopOf itu saja.

mohammad al-momani
sumber
Tolong jelaskan jawaban ini lebih lanjut, seperti contoh kode untuk diterapkan.
Jake
0

Bagi saya, tidak ada saran tentang menghapus batasan bawah atau mengatur wadah gulir ke true sepertinya berfungsi. Apa yang berhasil: perluas ketinggian tampilan individual / bersarang di tata letak saya sehingga mereka "membentang" di luar induk dengan menggunakan opsi "Expand Vertically" dari Constraint Layout Editor seperti yang ditunjukkan di bawah ini.

Untuk pendekatan apa pun, penting bahwa garis pratinjau bertitik memperpanjang secara vertikal melampaui dimensi atas atau bawah orangtua

Perluas Secara Vertikal

kip2
sumber