Ekranın altındaki görünümleri nasıl hizalarım?


636

İşte düzen kodum;

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

Bunun neye benzediği solda ve neye benzemesini istediğim sağda.

Android Düzeni - Gerçek (Sol) ve İstenen (Sağ)

Açık cevap, TextView öğesini yükseklikte fill_parent olarak ayarlamaktır, ancak bu düğme veya giriş alanı için yer kalmasına neden olmaz.

Temelde sorun, gönderme düğmesi ve metin girişinin altta sabit bir yükseklik ve metin görünümünün alanın geri kalanını doldurmasını istiyorum. Benzer şekilde, yatay doğrusal mizanpajda, gönder düğmesinin içeriğini kaydırmasını ve metin girişinin alanın geri kalanını doldurmasını istiyorum.

Doğrusal mizanpajdaki ilk öğeye fill_parent olduğu söylenirse, bunu tam olarak yapar ve diğer öğelere yer bırakmaz. Düzendeki ilk öğe olan bir öğeyi, mizanpajdaki diğer öğelerin gerektirdiği minimum alan dışında tüm alanı dolduracak şekilde nasıl alabilirim?


Göreceli düzenler gerçekten de cevaptı:

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

7
@oneself Paint;) Tea Vui Huang'ın izniyle olsa da emülatörde bir cilt kullanıyorum teavuihuang.com/android
gav

14
Çözen XML düzenini göndermek için +1. Bana neyin yanlış olduğunu anlamama yardımcı oldu.
Howler

Yanıtlar:


527

Bunu yapmanın modern yolu, bir ConstraintLayout'a sahip olmak ve görünümün altını ConstraintLayout'un altına sınırlamaktır.app:layout_constraintBottom_toBottomOf="parent"

Aşağıdaki örnek, ekranın sonuna ve altına hizalanacak bir FloatingActionButton öğesi oluşturur.

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

Referans olarak, eski cevabımı saklayacağım.

ConstraintLayout girişinden önce cevap göreceli bir düzendi .


Tüm ekranı kaplayan göreceli bir düzeniniz varsa android:layout_alignParentBottom, düğmeyi ekranın altına taşımak için kullanabilmeniz gerekir .

En alttaki görünümleriniz göreceli bir düzende gösterilmiyorsa, belki de yukarıdaki düzen tüm alanı kaplar. Bu durumda, ilk önce olması gereken görünümü mizanpaj dosyanızın içine yerleştirebilir ve mizanpajın geri kalanını görünümlerin üzerine yerleştirebilirsiniz android:layout_above. Bu, alt görünümün ihtiyaç duyduğu kadar yer kaplamasını sağlar ve mizanpajın geri kalanı ekranın geri kalanını doldurabilir.


5
Bilginize: ScrollView içinde çalışmaz. Şu an karşılaştığım sorun bu. Bkz. Stackoverflow.com/questions/3126347/…
IgorGanapolsky

6
Doğru ScrollViews ve Relative Layouts çok iyi karışmıyor. Her şeyi tek bir sayfada görüntülemek için çok fazla içeriğe ihtiyacınız varsa, bir doğrusal yerleşim kullanın ve en son olarak alt görünüme koyun. Görünümün en son küçük ekranlarda ve sayfanın alt kısmında büyük telefonlarda görünmesini istiyorsanız, farklı düzen dosyaları kullanmayı düşünün ve aygıtın doğru düzen dosyasını seçmesine izin vermek için kaynak niteleyicileri kullanın.
Janusz

tamam .. cevabın ikinci paragrafının anlamı nedir? "Önce ekranın altını kaplayan bir düzen bulmalısınız"? o zaman mizanpaj içinde layout_alignParentBottom kullanmalıyız? Ne android:layout_aboveiçin ihtiyacımız var ?
eugene

Altta bir çubuk gibi bir şey istiyorsanız ve ekranın üst kısmından çubuğa uzanan bu çubuğun üstünde bir LinearLayout'a ihtiyacınız var.
Janusz

1
Ben "Android Weekly" birinde that RelativeLayoutbellek tüketen biri okudum ve mümkün olduğunda kaçınılmalıdır.
Tomasz Mularczyk

153

Birinde ScrollViewbu işe yaramaz, çünkü sayfanın altındaki RelativeLayouther şeyle çakışır ScrollView.

Ben dinamik olarak uzanan kullanarak sabit 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>

1
bu harika - aynı zamanda, "minimal invaziv" ve RelativeLayout yaklaşımından daha sezgisel. Yapabilseydim birden fazla oy verirdim!
manmal

4
Çözümümü uygulamamda kullanıyorum, ancak benim durumumda klavye göründüğünde, düğmelerin ekranın altında kalmasını istiyorum (klavyenin arkasında) Bunun için bir kükürt var mı? Thaks.
Yoann

1
@DoubleYo: manifest android'de: windowSoftInputMode = "adjustPan"
Kopfgeldjaeger

2
Eğer tabanın kalıcı olarak sabitlenmesini istiyorsanız, bu her zaman çalışmadığını gösterir. Aksi takdirde çalışır.
K - SO'da toksisite artıyor.

72

İlk doğrusal mizanpajınızı, göreli mizanpajı doğrusal mizanpaj içine yerleştirerek tutabilirsiniz:

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

2
Bu çok modüler olmadığı için dağınık bir yaklaşımdır. Çakışan mizanpajlarınız olmamalıdır. Bu tasarım, RelativeLayout'un arka planını değiştirmek veya görünümlerden herhangi birini büyütmek veya görünüm eklemek istediğinizde çalışmaz.
Patrick

42

Yukarıdaki cevap (Janusz tarafından) oldukça doğrudur, ancak şahsen RelativeLayouts ile% 100 konforlu hissetmiyorum, bu yüzden şöyle bir 'dolgu', boş TextView tanıtmayı tercih ediyorum:

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

ekranın altında olması gereken öğeden önce.


Bu x veya y eksenine mi genişleyecek? Yükseklik için 0dip vermek, metin görünümünü herhangi bir yükseklik olmadan yapar mı? ya da x eksenine olabildiğince genişleyecek?
Lukap

Yükseklik (dikey eksen) 0 ve ağırlık 1'e ayarlandığı için bu dikey olarak genişler (diğer elemanların sıfır ağırlığa sahip olduğu varsayılarak).
Timores

X ekseninde, üst
öğesi

Bir metin görünümünden ziyade başka bir doğrusal düzen kullanırdım. Yerleşim görünümü, alanı doldurmak için kullanılabileceği anlamına geliyor mu?
17'de

33

Bunu bir LinearLayout veya ScrollView ile de yapabilirsiniz. Bazen bir RelativeLayout'tan daha kolaydır. Yapmanız gereken tek şey , ekranın altına hizalamak istediğiniz Görünümlerden önce aşağıdaki görünümü eklemektir :

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

Bu, boş alanı doldurarak boş alanı doldurur ve sonraki görünümleri ekranın altına doğru iter.


27

Bu da işe yarıyor.

<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" LinearLayout öğelerini alta yüzer


12
android: layout_alignParentBottom = "true", LinearLayout bir RelativeLayout içine yerleştirilmedikçe hiçbir etkisi yoktur.
Thomas Dignan

Bir açıklama uygun olacaktır (örn. Temel değişiklik, nasıl çalıştığı, neden çalıştığı vb.).
Peter Mortensen

26

1. ConstraintLayoutKök Düzeni'nizde kullanın

Ve app:layout_constraintBottom_toBottomOf="parent"ekranın altındaki Düzen'e izin verecek şekilde ayarlayın :

<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. FrameLayoutKök Düzeni'nizde kullanın

Sadece android:layout_gravity="bottom"düzeninizi ayarlayın

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

3. LinearLayoutKök Düzeni'nizde kullanın ( android:orientation="vertical")

(1) Mizanpajınızın android:layout_weight="1"üstünde bir düzen ayarlayın

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

(2) çocuk Set LinearLayoutiçinandroid:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"

Ana özellik, ndroid:gravity="bottom"Düzen'in alt kısmında çocuğun görmesine izin vermesidir.

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

4. RelativeLayoutKök Düzeni'nde kullanın

Ve android:layout_alignParentBottom="true"ekranın altındaki Düzen'e izin vermek için ayarlayın

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

Çıktı

Resim açıklamasını buraya girin


20

Takip etmek Timores zarif çözümü , ben şu dikey LinearLayout ve yatay LinearLayout yatay dolgu dikey dolguyu oluşturur bulduk:

<Space
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" />

@sepehr Çözümümün işe yaramadığı bir durumda, başka bir faktör daha olmalı. Çözümümü bir parça düzeninde denedim ve orada da çalışıyor.
stevehs17

ağırlıklar doğrusal düzenlerde desteklenir ve @sepehr parçalar, etkinlikler, bildirimler, diyaloglarda da çalışacaklardır;)
Jan Rabe

16

İkinci relativedüzeni birincinin içine yerleştirmeniz bile gerekmez . Basitçe kullanmak android:layout_alignParentBottom="true"içinde Düğme ve EditText .


Bu, Button ve EditText ile çalışmasına rağmen, bir TableLayout'u bu şekilde hizalamaya çalıştığınızda işe yaramayacağını unutmayın. Başka bir RelativeLayout içine yerleştirmeniz gerekir.

11

Çok fazla değişiklik yapmak istemiyorsanız, şunları yapabilirsiniz:

android:layout_weight="1"

@+id/TextViewie olarak kimliğe sahip TextView için

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

Veya android ile çevreleyen bir LinearLayout ekleyin: layout_weight = "1" - bu da bir ScrollView içinde iyi çalışır!
bk138

7

Her iki Oluşturma başlığını ve alt bilgi , burada bir örnek:

Düzen 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>

Ekran görüntüsü

Resim açıklamasını buraya girin


4

Aşağıdaki kodu kullanın. Düğmeyi buttom ile hizalayın. İşe yarıyor.

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

3

Böyle bir durum için daima RelativeLayouts kullanın. LinearLayout bu tür bir kullanım için tasarlanmamıştır.

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

2

Kullanım android:layout_alignParentBottom="true" Sepetinde <RelativeLayout>.

Bu kesinlikle yardımcı olacaktır.


1
Bu, kullanıcının bir RelativeLayout kullanmak istediğini varsayar.
IgorGanapolsky

2

Böyle bir hiyerarşiniz varsa:

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

Birincisi, uygulamak android:fillViewport="true"için ScrollViewve sonra uygulamak android:layout_alignParentBottom="true"için LinearLayout.

Bu benim için mükemmel çalıştı.

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

2

Sadece kendi üst çocuk görünüm verebilir (TextView + id / TextView ) bir öznitelik: android:layout_weight="1".

Bu, altındaki diğer tüm öğeleri tabana zorlar.


2

Bu doğrusal bir düzen ile de yapılabilir.

Yukarıdaki düzene ve altta istediğiniz düzene Yükseklik = 0dp ve ağırlık = 1 sağlamanız yeterlidir. Sadece height = wrap içeriği yazın ve ağırlık yok.

Düzen için kaydırma içeriği sağlar (düzenleme metninizi ve düğmenizi içeren içerik) ve ardından ağırlığı olan içerik düzenin geri kalanını kaplar.

Bunu kazara keşfettim.


0

Janusz'un yayınladığı çözümü kullandım, ancak mizanpajımın üst kısmı bir ScrollView olduğu için son görünüme dolgu ekledim.

ScrollView, içerikle birlikte büyüdükçe kısmen gizlenir. android:paddingBottomSon Görünümde kullanmak , ScrollView'daki tüm içeriğin gösterilmesine yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.