Wie richte ich Ansichten am unteren Bildschirmrand aus?

634

Hier ist mein Layoutcode;

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

Wie das aussieht, ist links und wie es aussehen soll, ist rechts.

Android Layout - Ist (links) und Gewünscht (rechts)

Die offensichtliche Antwort besteht darin, die Textansicht in der Höhe auf fill_parent zu setzen. Dadurch bleibt jedoch kein Platz mehr für die Schaltfläche oder das Eingabefeld.

Im Wesentlichen besteht das Problem darin, dass die Schaltfläche "Senden" und die Texteingabe unten eine feste Höhe haben sollen und die Textansicht den Rest des Bereichs ausfüllt. In ähnlicher Weise möchte ich, dass im horizontalen linearen Layout die Schaltfläche "Senden" den Inhalt umschließt und die Texteingabe den Rest des Bereichs ausfüllt.

Wenn das erste Element in einem linearen Layout aufgefordert wird, fill_parent auszuführen, wird genau das ausgeführt, sodass kein Platz für andere Elemente bleibt. Wie erhalte ich ein Element, das sich zuerst in einem linearen Layout befindet, um den gesamten Raum bis auf das Minimum auszufüllen, das für die übrigen Elemente im Layout erforderlich ist?


Relative Layouts waren in der Tat die Antwort:

    <?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
quelle
7
@oneself Paint;) Ich benutze einen Skin auf dem Emulator, obwohl mit freundlicher Genehmigung von Tea Vui Huang teavuihuang.com/android
gav
14
+1 für das Posten des Layout-XML, das es gelöst hat. Hat mir geholfen herauszufinden, was mit meinem los war.
Howler

Antworten:

526

Der moderne Weg, dies zu tun, besteht darin, ein ConstraintLayout zu haben und den unteren Rand der Ansicht auf den unteren Rand des ConstraintLayout mit zu beschränkenapp:layout_constraintBottom_toBottomOf="parent"

Im folgenden Beispiel wird ein FloatingActionButton erstellt, der am Ende und am unteren Rand des Bildschirms ausgerichtet wird.

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

Als Referenz werde ich meine alte Antwort behalten.

Vor der Einführung von ConstraintLayout war die Antwort ein relatives Layout .


Wenn Sie ein relatives Layout haben, das den gesamten Bildschirm ausfüllt, sollten Sie in der Lage sein, android:layout_alignParentBottomdie Schaltfläche an den unteren Bildschirmrand zu verschieben.

Wenn Ihre Ansichten unten nicht in einem relativen Layout angezeigt werden, nimmt das darüber liegende Layout möglicherweise den gesamten Platz ein. In diesem Fall können Sie die Ansicht, die sich unten befinden sollte, zuerst in Ihre Layoutdatei einfügen und den Rest des Layouts über den Ansichten mit positionieren android:layout_above. Dadurch kann die Unteransicht so viel Platz beanspruchen, wie sie benötigt, und der Rest des Layouts kann den gesamten Rest des Bildschirms ausfüllen.

Janusz
quelle
5
Zu Ihrer Information: Das würde in einer ScrollView nicht funktionieren. Dies ist das Problem, mit dem ich jetzt konfrontiert bin. Siehe stackoverflow.com/questions/3126347/…
IgorGanapolsky
6
Das ist richtig. ScrollViews und relative Layouts lassen sich nicht sehr gut mischen. Wenn Sie zu viel Inhalt haben, um alles auf einer Seite anzuzeigen, verwenden Sie einfach ein lineares Layout und setzen Sie es zuletzt in die Unteransicht. Wenn Sie möchten, dass die Ansicht zuletzt in der Bildlaufansicht auf kleinen Bildschirmen und am Ende der Seite auf größeren Telefonen angezeigt wird, sollten Sie unterschiedliche Layoutdateien verwenden und Ressourcenqualifizierer verwenden, damit das Gerät die richtige Layoutdatei auswählen kann.
Janusz
ok .. was ist der Sinn des zweiten Absatzes der Antwort hier? "Sie sollten zuerst ein Layout finden, das den unteren Bildschirmrand abdeckt"? dann sollten wir layout_alignParentBottom innerhalb des Layouts verwenden? Wofür brauchen wir android:layout_above?
Eugene
Sie benötigen das Obige, wenn Sie eine Leiste unten und dann ein lineares Layout über dieser Leiste verwenden möchten, das sich vom oberen Bildschirmrand bis zur Leiste erstreckt.
Janusz
1
Ich habe in einem von "Android Weekly" gelesen, that RelativeLayoutist speicherintensiv und sollte vermieden werden, wann immer es möglich ist.
Tomasz Mularczyk
153

In einem ScrollViewFall funktioniert dies nicht, da RelativeLayoutsich dann alles überlappen würde, was sich ScrollViewunten auf der Seite befindet.

Ich habe es mit einer dynamischen Dehnung behoben 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
quelle
1
Das ist großartig - außerdem ist es "minimal invasiv" und intuitiver als der RelativeLayout-Ansatz. Ich würde mehr als eine Gegenstimme abgeben, wenn ich könnte!
Manmal
4
Ich verwende Ihre Lösung in meiner Anwendung, aber in meinem Fall möchte ich, dass die Tasten beim Anzeigen der Tastatur am unteren Bildschirmrand (hinter der Tastatur) bleiben. Gibt es dafür eine Lösung? Thaks.
Yoann
1
@DoubleYo: im Manifest android: windowSoftInputMode = "adjustPan"
Kopfgeldjaeger
2
WENN Sie möchten, dass der Boden dauerhaft fixiert wird, so dass dies immer angezeigt wird, funktioniert dies nicht. Sonst funktioniert es.
Karl Morrison
72

Sie können Ihr anfängliches lineares Layout beibehalten, indem Sie das relative Layout innerhalb des linearen Layouts verschachteln:

<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
quelle
2
Dies ist insofern ein chaotischer Ansatz, als er nicht sehr modular ist. Sie sollten keine überlappenden Layouts haben. Dieses Design funktioniert nicht, sobald Sie den Hintergrund des RelativeLayout ändern oder eine der Ansichten vergrößern oder Ansichten hinzufügen möchten.
Patrick
42

Die obige Antwort (von Janusz) ist ganz richtig, aber ich persönlich fühle mich mit RelativeLayouts nicht zu 100% wohl. Deshalb ziehe ich es vor, eine leere Textansicht wie folgt einzufügen:

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

vor dem Element, das sich am unteren Bildschirmrand befinden soll.

Timores
quelle
Wird sich das auf die x- oder y-Achse ausdehnen? Wenn Sie 0dip für die Höhe angeben, wird die Textansicht ohne Höhe angezeigt. oder wird sich so weit wie möglich auf die x-Achse ausdehnen?
Lukap
Dies wird vertikal erweitert, da die Höhe (vertikale Achse) auf 0 und das Gewicht auf 1 gesetzt ist (vorausgesetzt, andere Elemente haben ein Gewicht von Null).
Timores
Auf der x-Achse wird es als übergeordnetes Element (fill_parent) sein
Timores
Anstelle einer Textansicht würde ich ein anderes lineares Layout verwenden. Layout-Ansicht scheint zu implizieren, dass es verwendet werden kann, um Raum zu füllen?
Kommen Sie
33

Sie können dies auch mit einem LinearLayout oder einer ScrollView tun. Manchmal ist es einfacher zu implementieren als ein RelativeLayout. Sie müssen lediglich die folgende Ansicht vor den Ansichten hinzufügen, die Sie am unteren Bildschirmrand ausrichten möchten:

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

Dadurch wird eine leere Ansicht erstellt, die den leeren Bereich ausfüllt und die nächsten Ansichten an den unteren Bildschirmrand verschiebt.

Keybee
quelle
27

Das funktioniert auch.

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

Schwerkraft = "unten", um LinearLayout-Elemente nach unten zu schweben

Michael Reed
quelle
12
android: layout_alignParentBottom = "true" hat keine Auswirkung, es sei denn, das LinearLayout ist in einem RelativeLayout verschachtelt.
Thomas Dignan
Eine Erklärung wäre angebracht (z. B. die wesentliche Änderung, wie es funktioniert, warum es funktioniert usw.).
Peter Mortensen
26

1. Verwenden Sie ConstraintLayoutin Ihrem Root-Layout

Und stellen app:layout_constraintBottom_toBottomOf="parent"Sie das Layout am unteren Bildschirmrand ein:

<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. Verwenden Sie FrameLayoutin Ihrem Root-Layout

Stellen android:layout_gravity="bottom"Sie einfach Ihr Layout ein

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

3. Verwenden Sie LinearLayoutin Ihrem Root-Layout ( android:orientation="vertical")

(1) Legen Sie ein Layout android:layout_weight="1"oben in Ihrem Layout fest

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

(2) Stellen Sie das Kind LinearLayoutfür einandroid:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"

Das Hauptattribut ist ndroid:gravity="bottom", die untergeordnete Ansicht unten im Layout anzeigen zu lassen.

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

4. Verwenden Sie RelativeLayoutim Root-Layout

Und stellen android:layout_alignParentBottom="true"Sie das Layout am unteren Bildschirmrand ein

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

Ausgabe

Geben Sie hier die Bildbeschreibung ein

KeLiuyue
quelle
19

Nach Timores 'eleganter Lösung habe ich festgestellt, dass im Folgenden eine vertikale Füllung in einem vertikalen LinearLayout und eine horizontale Füllung in einem horizontalen LinearLayout erstellt wird:

<Space
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" />
stevehs17
quelle
@sepehr Es muss einen weiteren Faktor geben, falls Sie festgestellt haben, dass meine Lösung nicht funktioniert. Ich habe gerade meine Lösung in einem Fragment-Layout ausprobiert und es funktioniert auch dort.
stevehs17
Gewichte werden in linearen Layouts unterstützt und @sepehr funktionieren auch in Fragmenten, Aktivitäten, Benachrichtigungen und Dialogen;)
Jan Rabe
16

Sie müssen nicht einmal das zweite relativeLayout im ersten verschachteln . Verwenden Sie die einfach android:layout_alignParentBottom="true"in der Taste und EditText .

Steve Haley
quelle
Nur ein Hinweis, dass dies zwar mit Button und EditText funktioniert, aber nicht funktioniert, wenn Sie versuchen, ein TableLayout auf diese Weise auszurichten. Sie müssten es in einem anderen RelativeLayout verschachteln.
11

Wenn Sie nicht viele Änderungen vornehmen möchten, können Sie einfach Folgendes sagen:

android:layout_weight="1"

für die Textansicht mit der ID als @+id/TextViewdh

<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
quelle
Oder fügen Sie ein umgebendes LinearLayout mit Android hinzu: layout_weight = "1" - dies funktioniert auch gut in einer ScrollView!
bk138
7

Hier ein Beispiel zum Erstellen von Kopf- und Fußzeilen :

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>

Bildschirmfoto

Geben Sie hier die Bildbeschreibung ein

Madan Sapkota
quelle
4

Verwenden Sie den folgenden Code. Richten Sie die Schaltfläche auf Buttom aus. Es funktioniert.

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

Verwenden Sie in einem solchen Fall immer RelativeLayouts. Ein LinearLayout ist für eine solche Verwendung nicht vorgesehen.

<?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.
quelle
2

Verwenden Sie android:layout_alignParentBottom="true" in Ihrem <RelativeLayout>.

Dies wird definitiv helfen.

Jigar
quelle
1
Dies setzt voraus, dass der Benutzer ein RelativeLayout verwenden möchte.
Igor Ganapolsky
2

Falls Sie eine Hierarchie wie diese haben:

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

Erstens gelten android:fillViewport="true"auf das ScrollViewund wenden Sie dann android:layout_alignParentBottom="true"auf die LinearLayout.

Das hat bei mir perfekt funktioniert.

<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>
Prinz
quelle
2

Sie können Ihrer obersten untergeordneten Ansicht (TextView @ + id / TextView ) einfach ein Attribut geben : android:layout_weight="1".

Dadurch werden alle anderen Elemente darunter nach unten gedrückt.

IgorGanapolsky
quelle
2

Dies kann auch mit einem linearen Layout erfolgen.

Geben Sie einfach Höhe = 0 dp und Gewicht = 1 für das Layout oben und das gewünschte unten an. Schreiben Sie einfach height = Wrap Content und kein Gewicht.

Es enthält Zeilenumbruchinhalte für das Layout (das Ihren Bearbeitungstext und Ihre Schaltfläche enthält), und dasjenige, das Gewicht hat, nimmt den Rest des Layouts ein.

Ich habe das zufällig entdeckt.

Raihan Ahmed
quelle
0

Ich habe die von Janusz veröffentlichte Lösung verwendet, aber der letzten Ansicht wurde eine Auffüllung hinzugefügt, da der obere Teil meines Layouts eine ScrollView war.

Die ScrollView wird teilweise ausgeblendet, wenn sie mit dem Inhalt wächst. Wenn Sie android:paddingBottomdie letzte Ansicht verwenden, wird der gesamte Inhalt in der ScrollView angezeigt.

jeremyvillalobos
quelle