Bagaimana cara menyelaraskan tampilan di bagian bawah layar?

636

Ini kode tata letak saya;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView android:text="@string/welcome"
        android:id="@+id/TextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </TextView>

    <LinearLayout android:id="@+id/LinearLayout"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="bottom">

            <EditText android:id="@+id/EditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
            </EditText>

            <Button android:text="@string/label_submit_button"
                android:id="@+id/Button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
            </Button>

    </LinearLayout>

</LinearLayout>

Seperti apa ini di sebelah kiri dan apa yang saya inginkan di sebelah kanan.

Layout Android - Aktual (Kiri) dan Diinginkan (Kanan)

Jawaban yang jelas adalah untuk mengatur TextView ke fill_parent pada ketinggian, tetapi ini menyebabkan tidak ada ruang yang tersisa untuk tombol atau bidang entri.

Pada dasarnya masalahnya adalah bahwa saya ingin tombol kirim dan entri teks menjadi ketinggian tetap di bagian bawah dan tampilan teks untuk mengisi sisa ruang. Demikian pula, dalam tata letak linier horizontal saya ingin tombol kirim untuk membungkus kontennya dan untuk entri teks untuk mengisi sisa ruang.

Jika item pertama dalam tata letak linier diperintahkan untuk fill_parent itu melakukan hal itu, tidak meninggalkan ruang untuk item lain. Bagaimana cara mendapatkan item yang pertama dalam tata letak linier untuk mengisi semua ruang selain dari minimum yang diperlukan oleh sisa item dalam tata letak?


Layout relatif memang jawabannya:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:text="@string/welcome"
        android:id="@+id/TextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true">
    </TextView>

    <RelativeLayout
        android:id="@+id/InnerRelativeLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

        <Button
            android:text="@string/label_submit_button"
            android:id="@+id/Button"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </Button>

        <EditText
            android:id="@+id/EditText"
            android:layout_width="fill_parent"
            android:layout_toLeftOf="@id/Button"
            android:layout_height="wrap_content">
        </EditText>

    </RelativeLayout>

</RelativeLayout>
gav
sumber
7
@ Cat Diri;) Saya menggunakan skin pada emulator meskipun dari Tea Vui Huang teavuihuang.com/android
gav
14
+1 untuk memposting tata letak XML yang menyelesaikannya. Membantu saya mencari tahu apa yang salah dengan milik saya.
Howler

Jawaban:

527

Cara modern untuk melakukan ini adalah memiliki ConstraintLayout dan membatasi bagian bawah tampilan ke bagian bawah ConstraintLayout denganapp:layout_constraintBottom_toBottomOf="parent"

Contoh di bawah ini membuat FloatingActionButton yang akan diselaraskan dengan ujung dan bagian bawah layar.

<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_height="match_parent"
   android:layout_width="match_parent">

<android.support.design.widget.FloatingActionButton
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"

    app:layout_constraintBottom_toBottomOf="parent"

    app:layout_constraintEnd_toEndOf="parent" />

</android.support.constraint.ConstraintLayout>

Sebagai referensi, saya akan menyimpan jawaban lama saya.

Sebelum pengenalan ConstraintLayout jawabannya adalah tata letak yang relatif .


Jika Anda memiliki tata letak relatif yang memenuhi seluruh layar, Anda seharusnya dapat menggunakannya android:layout_alignParentBottomuntuk memindahkan tombol ke bagian bawah layar.

Jika tampilan Anda di bagian bawah tidak ditampilkan dalam tata letak relatif maka mungkin tata letak di atas ini membutuhkan semua ruang. Dalam hal ini Anda dapat menempatkan tampilan, yang harus di bagian bawah, pertama di file tata letak Anda dan posisikan sisa tata letak di atas tampilan dengan android:layout_above. Ini memungkinkan tampilan bawah untuk mengambil ruang sebanyak yang dibutuhkan, dan tata letak lainnya dapat mengisi semua sisa layar.

Janusz
sumber
5
FYI: itu tidak akan berfungsi di dalam ScrollView. Ini adalah masalah yang saya hadapi sekarang. Lihat stackoverflow.com/questions/3126347/…
IgorGanapolsky
6
Itu benar ScrollViews dan Layout Relatif tidak bercampur dengan sangat baik. Jika Anda harus banyak konten untuk menampilkan semuanya di satu halaman cukup gunakan linearlayout dan letakkan di bagian bawah tampilan terakhir. Jika Anda ingin tampilan muncul terakhir di layar gulir pada layar kecil dan di bagian bawah halaman pada ponsel yang lebih besar pertimbangkan untuk menggunakan file tata letak yang berbeda dan menggunakan kualifikasi sumber daya ressource untuk membiarkan perangkat memilih file tata letak yang benar.
Janusz
ok .. apa gunanya jawaban paragraf kedua di sini? "Anda harus menemukan tata letak yang menutupi bagian bawah layar terlebih dahulu"? maka kita harus menggunakan layout_alignParentBottom di dalam layout? Apa yang kita butuhkan android:layout_above?
eugene
Anda memerlukan hal di atas jika Anda ingin sesuatu seperti bilah di bagian bawah dan kemudian LinearLayout di atas bilah ini yang membentang dari bagian atas layar ke bilah.
Janusz
1
Saya telah membaca di salah satu "Android Weekly" that RelativeLayoutyang menghabiskan banyak memori dan harus dihindari kapan pun memungkinkan.
Tomasz Mularczyk
153

Dalam ScrollViewhal ini tidak berfungsi, karena RelativeLayoutakan tumpang tindih dengan apa pun yang ada di ScrollViewbagian bawah halaman.

Saya memperbaikinya menggunakan peregangan dinamis FrameLayout:

<ScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent" 
    android:layout_width="match_parent"
    android:fillViewport="true">
    <LinearLayout 
        android:id="@+id/LinearLayout01"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical">

                <!-- content goes here -->

                <!-- stretching frame layout, using layout_weight -->
        <FrameLayout
            android:layout_width="match_parent" 
            android:layout_height="0dp"
            android:layout_weight="1">
        </FrameLayout>

                <!-- content fixated to the bottom of the screen -->
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                                   <!-- your bottom content -->
        </LinearLayout>
    </LinearLayout>
</ScrollView>
Bram Avontuur
sumber
1
ini hebat - juga, "invasif minimal", dan lebih intuitif daripada pendekatan RelativeLayout. Saya akan memberikan lebih dari satu suara jika saya bisa!
manmal
4
Saya menggunakan solusi Anda di aplikasi saya, tetapi dalam kasus saya, saya ingin bahwa ketika keyboard muncul, tombol tetap di bagian bawah layar (di belakang keyboard) Ada kecurangan untuk itu? Thak.
Yoann
1
@DoubleYo: di manifes android: windowSoftInputMode = "AdjustPan"
Kopfgeldjaeger
2
JIKA Anda ingin bagian bawah diperbaiki secara permanen sehingga ditampilkan sepanjang waktu ini tidak berfungsi. Kalau tidak berhasil.
K - Keracunan dalam SO tumbuh.
72

Anda dapat mempertahankan tata letak linier awal Anda dengan menumpuk tata letak relatif dalam tata letak linier:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView android:text="welcome" 
        android:id="@+id/TextView" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content">
    </TextView>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button android:text="submit" 
            android:id="@+id/Button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true">
        </Button>
        <EditText android:id="@+id/EditText" 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/Button"
            android:layout_alignParentBottom="true">
        </EditText>
    </RelativeLayout>
</LinearLayout>
pseudosudo
sumber
2
Ini adalah pendekatan yang berantakan karena tidak terlalu modular. Anda seharusnya tidak memiliki tata letak yang tumpang tindih. Desain ini tidak akan berfungsi segera setelah Anda ingin mengubah latar belakang RelativeLayout atau ingin membuat tampilan lebih besar atau menambah tampilan.
Patrick
42

Jawaban di atas (oleh Janusz) cukup benar, tetapi secara pribadi saya tidak merasa 100% nyaman dengan RelativeLayouts, jadi saya lebih suka memperkenalkan 'filler', kosong TextView, seperti ini:

<!-- filler -->
<TextView android:layout_height="0dip" 
          android:layout_width="fill_parent"
          android:layout_weight="1" />

sebelum elemen yang harus di bagian bawah layar.

Timores
sumber
Apakah ini akan diperluas ke sumbu x atau y. Memberikan tinggi 0dip akan membuat tampilan teks tanpa ketinggian? atau akan berkembang sebanyak itu seperti ingin x sumbu?
Lukap
Ini mengembang secara vertikal karena ketinggian (sumbu vertikal) diatur ke 0 dan berat ke 1 (dengan asumsi bahwa elemen lain memiliki bobot nol).
Timores
Pada sumbu x, itu akan menjadi seperti induknya (fill_parent)
Timores
Alih-alih tampilan teks, saya akan menggunakan tata letak linier lain. Layout view sepertinya menyiratkan dapat digunakan untuk mengisi ruang?
Datang
33

Anda dapat melakukannya dengan LinearLayout atau ScrollView juga. Terkadang lebih mudah diterapkan daripada RelativeLayout. Satu-satunya hal yang perlu Anda lakukan adalah menambahkan tampilan berikut sebelum Tampilan yang ingin Anda selaraskan ke bagian bawah layar:

<View
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:layout_weight="1" />

Ini menciptakan tampilan kosong, mengisi ruang kosong dan mendorong tampilan berikutnya ke bagian bawah layar.

keybee
sumber
27

Ini juga berfungsi.

<LinearLayout 
    android:id="@+id/linearLayout4"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_below="@+id/linearLayout3"
    android:layout_centerHorizontal="true"
    android:orientation="horizontal" 
    android:gravity="bottom"
    android:layout_alignParentBottom="true"
    android:layout_marginTop="20dp"
>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 

    />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 


    />

</LinearLayout>

gravity = "bottom" untuk mengapungkan elemen LinearLayout ke bawah

Michael Reed
sumber
12
android: layout_alignParentBottom = "true" tidak memiliki efek kecuali LinearLayout bersarang di dalam RelativeLayout.
Thomas Dignan
Penjelasan akan dilakukan secara berurutan (mis. Perubahan penting, cara kerjanya, mengapa itu bekerja, dll.).
Peter Mortensen
26

1. Gunakan ConstraintLayoutdi Layout root Anda

Dan atur app:layout_constraintBottom_toBottomOf="parent"untuk membiarkan Tata Letak di bagian bawah layar:

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>

2. Gunakan FrameLayoutdi Layout root Anda

Cukup atur android:layout_gravity="bottom"di tata letak Anda

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

3. Gunakan LinearLayoutdi Layout root Anda ( android:orientation="vertical")

(1) Atur tata letak android:layout_weight="1"di bagian atas Tata Letak Anda

<TextView
    android:id="@+id/TextView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:text="welcome" />

(2) Tetapkan anak LinearLayoutuntukandroid:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"

Atribut utamanya adalah ndroid:gravity="bottom", biarkan anak Lihat di bagian bawah Layout.

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

4. Gunakan RelativeLayoutdi Layout root

Dan atur android:layout_alignParentBottom="true"untuk membiarkan Layout di bagian bawah layar

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:orientation="horizontal">
</LinearLayout>

Keluaran

Masukkan deskripsi gambar di sini

KeLiuyue
sumber
20

Menindaklanjuti solusi elegan Timores , saya telah menemukan bahwa yang berikut ini membuat isian vertikal dalam LinearLayout vertikal dan isian horizontal dalam LinearLayout horizontal:

<Space
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" />
stevehs17
sumber
@sepehr Pasti ada faktor lain yang berperan dalam kasus Anda menemukan di mana solusi saya tidak berfungsi. Saya baru saja mencoba solusi saya dalam tata letak fragmen, dan itu bekerja di sana juga.
stevehs17
bobot didukung dalam tata letak linier dan @sepehr mereka akan bekerja dalam fragmen, aktivitas, notifikasi, dialog juga;)
Jan Rabe
16

Anda bahkan tidak perlu membuat relativelayout tata letak kedua di dalam yang pertama. Cukup gunakan android:layout_alignParentBottom="true"di Button dan EditText .

Steve Haley
sumber
Hanya perhatikan bahwa meskipun ini berfungsi dengan Button dan EditText, jika Anda mencoba menyelaraskan TableLayout dengan cara ini tidak akan berfungsi. Anda harus menyimpannya di dalam RelativeLayout lain.
11

Jika Anda tidak ingin membuat banyak perubahan, maka Anda bisa memasukkan:

android:layout_weight="1"

untuk TextView memiliki ID sebagai @+id/TextViewmis

<TextView android:text="@string/welcome" 
    android:id="@+id/TextView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_weight="1">
</TextView>
Kiran Parmar
sumber
Atau tambahkan LinearLayout di sekitarnya dengan android: layout_weight = "1" - ini juga berfungsi baik di dalam ScrollView!
bk138
7

Membuat header dan footer , berikut adalah contohnya:

Layout XML

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/backgroundcolor"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:background="#FF0000">
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="#FFFF00">
    </RelativeLayout>

</RelativeLayout>

Tangkapan layar

Masukkan deskripsi gambar di sini

Madan Sapkota
sumber
4

Gunakan kode di bawah ini. Sejajarkan tombol untuk buttom. Bekerja.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn_back"
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:text="Back" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.97"
        android:gravity="center"
        android:text="Payment Page" />

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

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Submit"/>
    </LinearLayout>

</LinearLayout>
sharma_kunal
sumber
3

Untuk kasus seperti ini, selalu gunakan RelativeLayouts. LinearLayout tidak dimaksudkan untuk penggunaan seperti itu.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/db1_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- Place your layout here -->

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        android:orientation="horizontal"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >

        <Button
            android:id="@+id/setup_macroSavebtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Save" />

        <Button
            android:id="@+id/setup_macroCancelbtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Cancel" />

        </LinearLayout>

</RelativeLayout>
Shubham A.
sumber
2

Gunakan android:layout_alignParentBottom="true" di <RelativeLayout>.

Ini pasti akan membantu.

jigar
sumber
1
Itu mengandaikan pengguna ingin menggunakan RelativeLayout.
IgorGanapolsky
2

Jika Anda memiliki hierarki seperti ini:

<ScrollView> 
  |-- <RelativeLayout> 
    |-- <LinearLayout>

Pertama, terapkan android:fillViewport="true"ke ScrollViewdan kemudian terapkan android:layout_alignParentBottom="true"ke LinearLayout.

Ini bekerja dengan baik untuk saya.

<ScrollView
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:fillViewport="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/linearLayoutHorizontal"
            android:layout_alignParentBottom="true">
        </LinearLayout>
    </RelativeLayout>
</ScrollView>
Pangeran
sumber
2

Anda hanya bisa memberikan Anda pandangan anak atas (TextView @ + id / TextView ) atribut: android:layout_weight="1".

Ini akan memaksa semua elemen lain di bawahnya ke bawah.

IgorGanapolsky
sumber
2

Ini dapat dilakukan dengan tata letak linier juga.

Cukup berikan Tinggi = 0dp dan berat = 1 ke tata letak di atas dan yang Anda inginkan di bagian bawah. Cukup tulis tinggi = bungkus konten dan tanpa berat.

Ini memberikan bungkus konten untuk tata letak (yang berisi teks dan tombol edit Anda) dan kemudian yang memiliki berat menempati sisa tata letak.

Saya menemukan ini secara tidak sengaja.

raihan ahmed
sumber
0

Saya menggunakan solusi yang diposting Janusz, tetapi saya menambahkan padding ke tampilan terakhir karena bagian atas tata letak saya adalah ScrollView.

ScrollView akan disembunyikan sebagian karena bertambah dengan konten. Menggunakan android:paddingBottompada Tampilan terakhir membantu menampilkan semua konten di ScrollView.

jeremyvillalobos
sumber