Wie funktioniert ConstraintLayout mit Prozentwerten?

206

Mit einer Vorschau 1 von Android Studio 2.2 hat Google ein neues Layout in seiner Support-Bibliothek veröffentlicht : ConstraintLayout. Mit ConstraintLayout ist es einfacher, ein Design-Tool in Android Studio zu verwenden, aber ich habe keine Möglichkeit gefunden, relative Größen (Prozent oder 'Gewichte' wie in LinearLayout) zu verwenden. Gibt es eine Möglichkeit, die Einschränkungen basierend auf Prozenten zu definieren? ZB eine Ansicht 40% eines Bildschirms einnehmen lassen, einen Abstand von 20% zwischen den Ansichten erstellen und die Breite einer Ansicht auf 50% der Breite einer anderen Ansicht festlegen?

Yury Fedorov
quelle
3
Die prozentuale Unterstützung für Breite oder Höhe wurde in version 1.1ConstraintLayout hinzugefügt . Siehe "Prozentuale Dimension" unter developer.android.com/reference/android/support/constraint/… oder einige der neueren Antworten.
Sunadorer

Antworten:

225

Sie können dies derzeit auf verschiedene Arten tun.

Eine besteht darin, Richtlinien zu erstellen (klicken Sie mit der rechten Maustaste auf den Entwurfsbereich und dann auf vertikale / horizontale Richtlinie hinzufügen). Sie können dann auf die "Kopfzeile" der Richtlinie klicken, um die Positionierung prozentual zu ändern. Schließlich können Sie Ansichten auf Richtlinien beschränken.

Eine andere Möglichkeit besteht darin, eine Ansicht mithilfe von Bias (Prozent) zu positionieren und dann andere Ansichten in dieser Ansicht zu verankern.

Wir haben jedoch darüber nachgedacht, wie prozentuale Dimensionen angeboten werden können. Ich kann kein Versprechen abgeben, aber wir möchten es hinzufügen.

Romain Guy
quelle
1
0 down Abstimmung Kann ich um ein Follow-up bitten? Ich versuche, eine ImageView auf 60% Breite einzustellen, aber ein Seitenverhältnis von 16: 9 beizubehalten. Ich möchte, dass die Breite festgelegt wird, aber die Höhe der ImageView dynamisch ist. Ist das mit ConstraintLayout möglich? Ich habe Probleme, es zum Laufen zu bringen. Am Ende habe ich feste Werte für Breite / Höhe von 0, es sei denn, ich gebe fest codierte Abmessungen an.
MattWilliams89
3
@ MattWilliams89 Es gibt einen Parameter namens layout_constraintDimensionRatio. Ich denke, es kann in Ihrem Fall nützlich sein, schreiben Sie dort "16: 9". Es ist mir jedoch nicht gelungen, Ihr Layout damit zu erstellen. Das Bild wird riesig
Yury Fedorov,
1
@RomainGuy Wie ändern Sie die Positionierung in Prozent auf der Kopfzeile der Richtlinien?. Ich habe versucht, mit der rechten
Maustaste darauf
21
Für diejenigen, die sich genau fragen, was die Überschrift der Richtlinie ist, ist es der Kreis, der einen Aufwärts- oder Abwärtspfeil oder ein Prozentzeichen hat. Wenn Sie darauf klicken, wird in XML zwischen App: layout_constraintGuide_begin, App: layout_constraintGuide_end und App: layout_constraintGuide_percent umgeschaltet. Ich bin auf ein kleines Problem gestoßen (in ConstraintLayout Version 1.0.0-alpha8 musste ich auf die Richtlinie klicken, die Maus gedrückt halten und in den Kreis ziehen, um diese im Editor umzuschalten, aber ich bin sicher, dass dieser Fehler bald behoben wird .
lustig
4
Sie können dies auch in der XML des Layouts mitapp:layout_constraintGuide_percentage
piratemurray
215

Es kann nützlich sein, hier eine Kurzreferenz zu haben.

Platzierung von Ansichten

Verwenden Sie eine Richtlinie mit app:layout_constraintGuide_percentwie folgt aus :

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5"/>

Und dann können Sie diese Richtlinie als Ankerpunkte für andere Ansichten verwenden.

oder

Verwenden Sie Bias mit app:layout_constraintHorizontal_biasund / oder app:layout_constraintVertical_bias, um die Ansichtsposition zu ändern, wenn der verfügbare Speicherplatz dies zulässt

<Button
    ...
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintHorizontal_bias="0.25"
    ...
    />

Größe der Ansichten

Ein weiterer prozentualer Wert ist die Höhe und / oder Breite der Elemente mit app:layout_constraintHeight_percentund / oder app:layout_constraintWidth_percent:

<Button
    ...
    android:layout_width="0dp"
    app:layout_constraintWidth_percent="0.5"
    ...
    />
Amir Uval
quelle
3
Warum ist die Breite auf 1 dp eingestellt?
user924
1
@ user924 Es wäre sinnvoll gewesen, einer Richtlinie eine Breite von 0 dp zu geben. Ich weiß nicht, warum sich die Entwickler, die dies implementiert haben, für 1 dp entschieden haben. Vielleicht, weil 0dp bei der Verwendung von Gewichten als "Stretch" angesehen wird.
Amir Uval
3
@ user924: 0dpwird in ConstraintLayout verwendet, um die dynamische Größe anzuzeigen. Siehe developer.android.com/reference/android/support/constraint/…
serv-inc
1
@ serv-inc, aber hier 1dpnicht 0dp... es ist das, worüber ich spreche
user924
3
@ user924: Sie müssen eine Breite festlegen. 0dpist bereits reserviert, 1dpscheint also sinnvoll.
serv-inc
109

Ab "ConstraintLayout1.1.0-beta1" können Sie Breiten und Höhen in Prozent definieren.

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent=".4"

Dadurch wird die Breite auf 40% der Bildschirmbreite festgelegt. Eine Kombination aus diesem und Richtlinien in Prozent ermöglicht es Ihnen, jedes gewünschte prozentuale Layout zu erstellen.

Hoford
quelle
6
In constraint Layout 1.0.2 der Prozent - Wert für layout_constraintWidth_default wird nicht unterstützt. Ich denke, der richtige Weg ist, die Richtlinie zu verwenden.
Vovahost
1
Es funktioniert mit Android Studio 3.0, das am 20. Oktober 2017 erstellt wurde
Douarbou
5
Wie in der Antwort angegeben, wurde dies in version 1.1ConstraintLayout hinzugefügt . Das zusätzliche _default="percent"wird bei der stabilen Version nicht mehr benötigt! Siehe "Prozentuale Dimension" auf developer.android.com/reference/android/support/constraint/…
sunadorer
@hoford: Wie kann die Textgröße für eine Ansicht mit Text, deren Größe in spEinheiten definiert werden soll, automatisch proportional zur Größe der Ansicht sein (die für sich genommen proportional zur Gesamtgröße des Layouts definiert ist, dh in Prozent)? ?
Glückseligkeit
77

Mit der neuen Version von ConstraintLayout v1.1 können Sie jetzt Folgendes tun:

<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintWidth_percent="0.65" />

Dadurch wird die Schaltfläche auf 20% der Höhe und 65% der Breite der übergeordneten Ansicht beschränkt.

Adam
quelle
1
für mich funktionierte nur, als ich von "android:" zu "app:" wechselte -> app: layout_constraintHeight_percent = "0.2"
Kirill Karmazin
Dies ist ein Muss für mich, wenn ich dem fließenden Layout der Materialgestaltung folge. material.io/design/layout/…
@Adam: Wie kann die Textgröße für eine Ansicht mit Text, deren Größe in spEinheiten definiert werden soll, automatisch proportional zur Größe der Ansicht sein (die für sich genommen proportional zur Gesamtgröße des Layouts definiert ist, dh in Prozent)? ?
Glückseligkeit
1
@Bliss Klingt so, als könnte dies helfen: developer.android.com/guide/topics/ui/look-and-feel/… Ich habe es jedoch selbst nie benutzt.
Adam
43

Verwendung von Richtlinien

Die akzeptierte Antwort ist etwas unklar, wie Richtlinien verwendet werden sollen und wie der "Header" lautet.

Schritte

Fügen Sie zuerst eine Richtlinie hinzu.

Geben Sie hier die Bildbeschreibung ein

Wählen Sie die Richtlinie aus oder verschieben Sie sie ein wenig, um die Einschränkungen sichtbar zu machen.

Geben Sie hier die Bildbeschreibung ein

Klicken Sie dann auf den runden Kreis (die "Überschrift"), bis er zu einem Prozent wird. Sie können diesen Prozentsatz dann auf 50% oder was auch immer Sie möchten ziehen.

Geben Sie hier die Bildbeschreibung ein

Danach können Sie Ihre Ansicht auf die Richtlinie beschränken, um einen bestimmten Prozentsatz des übergeordneten Elements (mithilfe match_constraintder Ansicht) festzulegen.

Geben Sie hier die Bildbeschreibung ein

Suragch
quelle
Wo soll der 'Header' sichtbar sein? Es erscheint meiner Ansicht nach nicht.
Marcel50506
@ Marcel50506, stellen Sie sicher, dass sowohl die Design- als auch die Blueprint-Ansicht angezeigt werden. Das gibt Ihnen die beste Chance, es zu sehen. Wenn Sie die Richtlinienzeile sehen können, klicken Sie darauf, um sie auszuwählen. Wenn Sie die Linie nicht sehen können, klicken Sie im Menü "Komponentenbaum" auf das Richtlinienelement, das sich auf der linken Seite befinden sollte (vorausgesetzt, Sie haben bereits eine Richtlinie hinzugefügt).
Suragch
1
Ich sehe den Kreis nicht, aber wenn ich links neben der Richtlinie klicke, kann ich ihn in Prozent ändern. Ich denke, Renderproblem. Danke dir.
Marcel50506
Dies ist die beste Antwort, da sie einen besseren Layoutansatz vorschlägt. Wir können mehrere Ansichten auf der Basisrichtlinie ausrichten, anstatt nur eine Ansicht mit einem Prozentsatz zu versehen
Nguyen Minh Hien,
33

Die Richtlinie ist von unschätzbarem Wert - und die App: layout_constraintGuide_percent ist ein guter Freund ... Manchmal möchten wir jedoch Prozentsätze ohne Richtlinien. Jetzt ist es möglich, Gewichte zu verwenden :

android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

Hier ist ein vollständigeres Beispiel, das eine Richtlinie mit zusätzlichen Gewichten verwendet :

<?xml version="1.0" encoding="utf-8"?>
<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:padding="16dp"
    tools:context="android.itomerbu.layoutdemo.MainActivity">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.44"/>

    <Button
        android:id="@+id/btnThird"
        android:layout_width="0dp"
        app:layout_constraintHorizontal_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/btnThird"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintRight_toLeftOf="@+id/btnTwoThirds"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"/>

    <Button
        android:id="@+id/btnTwoThirds"
        app:layout_constraintHorizontal_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/btnTwoThirds"
        app:layout_constraintBottom_toBottomOf="@+id/btnThird"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/btnThird"/>
</android.support.constraint.ConstraintLayout>
TomerBu
quelle
2
@Plumbus - Gewichte entsprechen Prozentsätzen (jeder Prozentsatz kann mathematisch in ein Gewicht umgewandelt werden und umgekehrt). Wenn Sie in Bezug auf die Terminologie nicht wählerisch sind, verpassen Sie den Punkt der Antwort.
Scott Biggs
11

Mit dem ConstraintLayout v1.1.2 sollte die Dimension auf 0dpund dann die Attribute layout_constraintWidth_percentoder layout_constraintHeight_percentauf einen Wert zwischen 0 und 1 gesetzt werden, wie:

<!-- 50% width centered Button -->
<Button
    android:id="@+id/button"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintWidth_percent=".5" />

(Sie müssen ConstraintLayout 1.1.2 und die folgenden Versionen nicht festlegen app:layout_constraintWidth_default="percent"oder verwenden. app:layout_constraintHeight_default="percent")

Bubu
quelle
9

Das Einschränken von Layout 1.0, mit dem eine Ansicht erstellt wird, nimmt einen Prozentsatz des Bildschirms ein, für den zwei Richtlinien erforderlich sind. In Constraint Layout 1.1 wurde dies vereinfacht, da Sie jede Ansicht einfach auf eine prozentuale Breite oder Höhe beschränken können.

Geben Sie hier die Bildbeschreibung ein

Ist das nicht fantastisch? Alle Ansichten unterstützen die Attribute layout_constraintWidth_percent und layout_constraintHeight_percent. Dadurch wird die Einschränkung auf einen Prozentsatz des verfügbaren Speicherplatzes festgelegt. Das Erweitern einer Schaltfläche oder einer Textansicht, um einen Prozent des Bildschirms auszufüllen, kann mit wenigen XML-Zeilen erfolgen.

Wenn Sie beispielsweise die Breite der Schaltfläche auf 70% des Bildschirms einstellen möchten, können Sie dies folgendermaßen tun:

<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_constraintWidth_percent="0.7" />

Bitte beachten Sie, dass Sie die Dimension als Prozentsatz für 0dp verwenden müssen, wie wir oben angegeben haben: layout_width bis 0dp.

Wenn Sie die Höhe der Schaltfläche auf 20% des Bildschirms einstellen möchten, können Sie dies folgendermaßen tun:

<Button
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_constraintHeight_percent="0.2" />

Sehen! Wir haben diesmal android: layout_height auf 0dp angegeben, da die Schaltfläche die Höhe als Prozentsatz verwenden soll.

Ashish Satpute
quelle
8

Versuchen Sie diesen Code. Sie können die Prozentsätze für Höhe und Breite mit app: layout_constraintHeight_percent und app: layout_constraintWidth_percent ändern.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#FF00FF"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent=".6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent=".4"></LinearLayout>

</android.support.constraint.ConstraintLayout>

Gradle:

dependencies {
...
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

Geben Sie hier die Bildbeschreibung ein

Live-Liebe
quelle
7

Sie können app:layout_constraintVertical_weightes genauso verwenden wie layout_weightinlinearlayout

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

<Button
    android:id="@+id/button4"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/button5"
    app:layout_constraintVertical_weight="1"/>

<Button
    android:id="@+id/button5"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toRightOf="@+id/button4"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintVertical_weight="1"/>
</android.support.constraint.ConstraintLayout>

HINWEIS: app:layout_constraintVertical_weight( app:layout_constraintHorizontal_weight) funktioniert mit android:layout_width="0dp"(android:layout_height="0dp"

vuhung3990
quelle
5

Für jemanden, der nützlich sein könnte, können Sie layout_constraintDimensionRatioim jede untergeordnete Ansicht in einem verwenden ConstraintLayoutund wir können die Höhe oder Breite als Verhältnis der anderen Dimension definieren (mindestens eine muss 0 dp sein, entweder Breite oder Höhe)

 <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:src="@drawable/top_image"
        app:layout_constraintDimensionRatio="16:9"        
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

In diesem Fall beträgt das Seitenverhältnis 16: 9. app:layout_constraintDimensionRatio="16:9" Weitere Informationen finden Sie HIER

Javier
quelle
3

Ich weiß, dass dies nicht direkt das ist, wonach OP ursprünglich gefragt hat, aber dies hat mir in dieser Situation sehr geholfen, als ich eine ähnliche Frage hatte. Hinzufügen für Leute, die die Größe des Layoutfensters (das ich regelmäßig verwende) über Code ändern möchten . Fügen Sie dies Ihrem onCreate in der Aktivität der Frage hinzu. (Ändert es auf 80%)

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

int width = dm.widthPixels;
int height = dm.heightPixels;

getWindow().setLayout((int)(width * 0.8), (int)(height * 0.8));
David Azzi
quelle
2

Einfach durch Ersetzen in Ihrem Richtlinien-Tag ersetzen

app:layout_constraintGuide_begin="291dp"

mit

app:layout_constraintGuide_percent="0.7"

wobei 0,7 70% bedeutet.

Auch wenn Sie jetzt versuchen, Richtlinien zu ziehen, wird der gezogene Wert jetzt in% Alter angezeigt.

Udit Kapahi
quelle
2

Mithilfe von Richtlinien können Sie die Positionierung prozentual ändern

<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>

Sie können diesen Weg auch verwenden

android:layout_width="0dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.4"
Ashish Satpute
quelle