Das Äquivalent von wrap_content und match_parent im Flattern?

124

In Android match_parentund wrap_contentwerden verwendet, um die Größe der Widgets automatisch relativ zu ihren übergeordneten Elementen auf den Inhalt des Widgets zu ändern.

In Flutter scheinen standardmäßig alle Widgets auf eingestellt zu sein wrap_content. Wie würde ich es so ändern, dass ich es widthund heightdas des übergeordneten Widgets füllen kann ?

Faisal Abid
quelle

Antworten:

160

Sie können mit kleinen Trick tun: Angenommen, Sie haben folgende Anforderungen: (Breite, Höhe)

Wrap_content, Wrap_content:

 //use this as child
 Wrap(
  children: <Widget>[*your_child*])

Match_parent, Match_parent:

 //use this as child
Container(
        height: double.infinity,
    width: double.infinity,child:*your_child*)

Match_parent, Wrap_content:

 //use this as child
Row(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[*your_child*],
);

Wrap_content, Match_parent:

 //use this as child
Column(
  mainAxisSize: MainAxisSize.max,
  children: <Widget>[your_child],
);
Sourav Pandit
quelle
2
Zum Match des Elternteils können Sie Ihre Widgets auch mit SizedBox.expand ()
Wecherowski
137

Um das Verhalten für match_parent und wrap_content zu erhalten , müssen wir die mainAxisSize- Eigenschaft im Zeilen- / Spalten- Widget verwenden. Die mainAxisSize- Eigenschaft verwendet die MainAxisSize-Enumeration mit zwei Werten: MainAxisSize.min, die sich wie wrap_content verhält, und MainAxisSize.max, die sich wie match_parent verhält .

Geben Sie hier die Bildbeschreibung ein

Link zum Originalartikel

fluffyBatman
quelle
6
Ich würde hinzufügen, dass es auch das crossAxisAlignmentFeld für Zeilen und Spalten gibt, das so eingestellt werden kann, dass es CrossAxisAlignment.stretchbeispielsweise innerhalb einer Spalte horizontal erweitert wird
wamfous
1
Vielen Dank! Ich habe letztes Jahr abgestimmt, dann habe ich lange nicht mehr geflattert und fast alles vergessen, und du hast mir heute wieder geholfen.
Chandler
33

Die kurze Antwort lautet, dass der Elternteil keine Größe hat, bis das Kind eine Größe hat.

Die Art und Weise, wie das Layout in Flutter funktioniert, besteht darin, dass jedes Widget jedem seiner untergeordneten Elemente Einschränkungen bietet, z. B. "Sie können bis zu dieser Breite sein, Sie müssen so groß sein, Sie müssen mindestens so breit sein" oder was auch immer (speziell sie) eine minimale Breite, eine maximale Breite, eine minimale Höhe und eine maximale Höhe erhalten). Jedes Kind nimmt diese Einschränkungen an, unternimmt etwas und wählt eine Größe (Breite und Höhe) aus, die diesen Einschränkungen entspricht. Sobald jedes Kind seine Sache erledigt hat, kann das Widget seine eigene Größe auswählen.

Einige Widgets versuchen so groß zu sein, wie es die Eltern erlauben. Einige Widgets versuchen so klein zu sein, wie es das übergeordnete Element zulässt. Einige Widgets versuchen, einer bestimmten "natürlichen" Größe zu entsprechen (z. B. Text, Bilder).

Einige Widgets teilen ihren Kindern mit, dass sie jede gewünschte Größe haben können. Einige geben ihren Kindern die gleichen Einschränkungen, die sie von ihren Eltern erhalten haben.

Ian Hickson
quelle
Ian, wenn ich ein PageViewInside a habe Column, mit einem anderen Columninnerhalb des Stroms page, erhalte ich einen Rendering-Fehler, aber ich kann ihn beheben, indem ich das PageViewInside a Expandedoder a umhülle Flexible. Das Problem ist, dass diese beiden Optionen nur das Kind erweitern. Warum gibt es kein verwandtes Widget zum Verkleinern, wie z. B. "Inhalt umbrechen", um diese Art von Rendering-Problemen zu lösen?
mFeinstein
21

Es gibt tatsächlich einige Optionen:

Sie können SizedBox.expand verwenden, um Ihr Widget an die Abmessungen der Eltern anzupassen, oder SizedBox (Breite: double.infinity), um nur der Breite zu entsprechen, oder SizedBox (Höhe: double.infinity), um nur der Höhe zu entsprechen.

Wenn Sie ein wrap_content-Verhalten wünschen, hängt es vom übergeordneten Widget ab, das Sie verwenden. Wenn Sie beispielsweise eine Schaltfläche in eine Spalte einfügen, verhält es sich wie wrap_content. Um es wie match_parent zu verwenden, können Sie die Schaltfläche mit einem erweiterten Widget oder einer Sizebox umschließen.

Bei einer ListView erhält die Schaltfläche ein match_parent-Verhalten. Um ein wrap_content-Verhalten zu erhalten, können Sie sie mit einem Flex-Widget wie Row umschließen.

Durch die Verwendung eines erweiterten Widgets wird ein untergeordnetes Element einer Zeile, Spalte oder eines Flex erweitert, um den verfügbaren Platz auf der Hauptachse zu füllen (z. B. horizontal für eine Zeile oder vertikal für eine Spalte). https://docs.flutter.io/flutter/widgets/Expanded-class.html

Durch die Verwendung eines flexiblen Widgets kann ein untergeordnetes Element einer Zeile, Spalte oder eines Flex flexibel erweitert werden, um den verfügbaren Platz auf der Hauptachse auszufüllen (z. B. horizontal für eine Zeile oder vertikal für eine Spalte), im Gegensatz zu "Erweitert" jedoch nicht Das Kind muss den verfügbaren Platz ausfüllen. https://docs.flutter.io/flutter/widgets/Flexible-class.html

David H Moreno
quelle
7

Eine einfache Problemumgehung:

Wenn ein Container nur ein untergeordnetes Element der obersten Ebene hat, können Sie die Ausrichtungseigenschaft für das untergeordnete Element angeben und ihm einen beliebigen verfügbaren Wert zuweisen. es wird den gesamten Raum im Container füllen.

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    alignment:Alignment.[any_available_option] // make the yellow child match the parent size
   )
)

Ein anderer Weg:

Container(color:Colors.white,height:200.0,width:200.0,
 child:Container(
    color: Colors.yellow,
    constraints:  BoxConstraints.expand(height: 100.0), // height will be 100 dip and width will be match parent
   )
)
behzad besharati
quelle
BoxConstraints.expand(height: 100.0)funktioniert hervorragend als Android- width="match_parent"Äquivalent
Kosiara - Bartosz Kosarzycki
6

Ich habe diese Lösung verwendet. Sie müssen die Höhe und Breite Ihres Bildschirms mit MediaQuery definieren:

 Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width
  )
Ayoub Boumzebra
quelle
5
Stack(
  children: [
    Container(color:Colors.red, height:200.0, width:200.0),
    Positioned.fill(
      child: Container(color: Colors. yellow),
    )
  ]
),
malibayram91
quelle
1
Obwohl Ihr Code die Frage möglicherweise beantwortet, sollte eine gute Antwort immer erklären, was der Code tut und wie er das Problem löst.
BDL
Dies ist keine Antwort auf den Wrap-Inhalt. Dies ist einfach fest codierte Breite und Höhe.
Entwickeln Sie
1

Verwenden Sie das Widget Wrap.

Für Columnähnliches Verhalten versuchen Sie:

  return Wrap(
          direction: Axis.vertical,
          spacing: 10,
          children: <Widget>[...],);

Für Rowähnliches Verhalten versuchen Sie:

  return Wrap(
          direction: Axis.horizontal,
          spacing: 10,
          children: <Widget>[...],);

Weitere Informationen: Wrap (Flutter Widget)

Farwa
quelle
0

Verwenden Sie diese Codezeile in der Spalte. Für wrap_content: mainAxisSize: MainAxisSize.min Für match_parent:mainAxisSize: MainAxisSize.max

Naveen Aluri
quelle
0

Es gibt tatsächlich einen sehr einfachen und ordentlichen Weg, dies zu tun.

Verwenden Sie FractionallySizedBoxWidget.

FractionallySizedBox(
  widthFactor: 1.0, // width w.r.t to parent
  heightFactor: 1.0,  // height w.r.t to parent
  child: *Your Child Here*
}

Dieses Widget ist auch sehr nützlich, wenn Sie Ihr Kind auf einen Bruchteil der Größe seines Elternteils skalieren möchten.

Beispiel:

Wenn Sie möchten, dass das Kind 50% der Breite seines Elternteils einnimmt, geben Sie widthFactoras an0.5

Mohammed Sadiq
quelle
0

Um ein Kind dazu zu bringen, sein Elternteil zu füllen, wickeln Sie es einfach in eine FittedBox ein

    FittedBox(
     child: Image.asset('foo.png'),
     fit: BoxFit.fill,
   )
Miraj Khandaker
quelle