Flattern - Einführung in Layouts

Da das Kernkonzept von Flutter ist Alles ist Widget , Flutter verfügt über eine Layout - Funktionalität Benutzeroberfläche in die Widgets selbst. Flutter bietet eine Vielzahl von speziell entwickelten Widgets wie Container, Center, Align usw., nur um die Benutzeroberfläche zu gestalten. Widgets, die durch Erstellen anderer Widgets erstellt werden, verwenden normalerweise Layout-Widgets. Lernen Sie das Flutter- Layout-Konzept in diesem Kapitel kennen.

Art der Layout-Widgets

Layout-Widgets können basierend auf ihrem untergeordneten Element in zwei verschiedene Kategorien eingeteilt werden:

  • Widget, das ein einzelnes Kind unterstützt
  • Widget, das mehrere Kinder unterstützt

Lassen Sie uns in den nächsten Abschnitten sowohl die Art der Widgets als auch deren Funktionalität kennenlernen.

Widgets für einzelne Kinder

In dieser Kategorie haben Widgets nur ein Widget als untergeordnetes Element, und jedes Widget verfügt über eine spezielle Layoutfunktion.

Zum Beispiel Zentrum Widget zentriert es nur Kind - Widget mit Bezug auf ihre Mutter Widget und Container - Widget vollständige Flexibilität bietet ihm zu platzieren Kind zu einem bestimmten Ort im Innern andere Option wie Polsterung, Dekoration usw. verwendet wird ,

Widgets für einzelne Kinder sind großartige Optionen, um hochwertige Widgets mit einzelnen Funktionen wie Schaltflächen, Beschriftungen usw. zu erstellen.

Der Code zum Erstellen einer einfachen Schaltfläche mit dem Container- Widget lautet wie folgt:

class MyButton extends StatelessWidget {
   MyButton({Key key}) : super(key: key); 

   @override 
   Widget build(BuildContext context) {
      return Container(
         decoration: const BoxDecoration(
            border: Border(
               top: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               left: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               right: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
               bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
            ),
         ),
         child: Container(
            padding: const
            EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
            decoration: const BoxDecoration(
               border: Border(
                  top: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  left: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
                  bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
               ),
               color: Colors.grey,
            ),
            child: const Text(
               'OK',textAlign: TextAlign.center, style: TextStyle(color: Colors.black)
            ), 
         ), 
      ); 
   }
}

Hier haben wir zwei Widgets verwendet - ein Container- Widget und ein Text- Widget. Das Ergebnis des Widgets ist eine benutzerdefinierte Schaltfläche (siehe unten).

Lassen wir uns von zur Verfügung gestellt einige der wichtigsten einzelne Kind Layout - Widgets überprüfen Flutter -

  • Padding- Wird verwendet, um das untergeordnete Widget anhand der angegebenen Polsterung anzuordnen. Hier kann das Auffüllen durch die EdgeInsets- Klasse bereitgestellt werden .

  • Align- Richten Sie das untergeordnete Widget mithilfe des Werts der Ausrichtungseigenschaft in sich selbst aus . Der Wert für die Ausrichtungseigenschaft kann von der FractionalOffset- Klasse bereitgestellt werden . Die FractionalOffset- Klasse gibt die Offsets als Abstand von oben links an.

Einige der möglichen Werte für Offsets sind wie folgt:

  • FractionalOffset (1.0, 0.0) steht oben rechts.

  • FractionalOffset (0.0, 1.0) steht unten links.

Ein Beispielcode für Offsets ist unten dargestellt -

Center(
   child: Container(
      height: 100.0, 
      width: 100.0, 
      color: Colors.yellow, child: Align(
         alignment: FractionalOffset(0.2, 0.6),
         child: Container( height: 40.0, width:
            40.0, color: Colors.red,
         ), 
      ), 
   ), 
)
  • FittedBox - Es skaliert das untergeordnete Widget und positioniert es dann entsprechend der angegebenen Anpassung.

  • AspectRatio - Es wird versucht, die Größe des untergeordneten Widgets auf das angegebene Seitenverhältnis zu ändern

  • ConstrainedBox

  • Baseline

  • FractinallySizedBox

  • IntrinsicHeight

  • IntrinsicWidth

  • LiimitedBox

  • OffStage

  • OverflowBox

  • SizedBox

  • SizedOverflowBox

  • Transform

  • CustomSingleChildLayout

Unsere Hallo-Welt-Anwendung verwendet materialbasierte Layout-Widgets, um die Homepage zu gestalten. Lassen Sie uns unsere Hallo-Welt-Anwendung so ändern, dass die Startseite mithilfe der unten angegebenen grundlegenden Layout-Widgets erstellt wird.

  • Container - Allgemeines, einzelnes untergeordnetes, boxbasiertes Container-Widget mit Ausrichtung, Auffüllung, Rand und Rand sowie umfangreichen Styling-Funktionen.

  • Center - Einfaches Widget für einen einzelnen untergeordneten Container, das das untergeordnete Widget zentriert.

Der geänderte Code des MyHomePage- und MyApp- Widgets lautet wie folgt:

class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
      return MyHomePage(title: "Hello World demo app");
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;
   @override
   Widget build(BuildContext context) {
      return Container(
         decoration: BoxDecoration(color: Colors.white,),
         padding: EdgeInsets.all(25), child: Center(
            child:Text(
               'Hello World', style: TextStyle(
                  color: Colors.black, letterSpacing: 0.5, fontSize: 20,
               ),
               textDirection: TextDirection.ltr,
            ),
         )
      );
   }
}

Hier,

  • Das Container- Widget ist das Top-Level- oder Root-Widget. Der Container wird mithilfe der Dekoration und der Polsterungseigenschaft konfiguriert, um seinen Inhalt zu gestalten.

  • BoxDecoration verfügt über viele Eigenschaften wie Farbe, Rahmen usw., um das Container- Widget zu dekorieren. Hier wird Farbe verwendet, um die Farbe des Containers festzulegen .

  • Das Auffüllen des Container- Widgets wird mithilfe der dgeInsets- Klasse festgelegt, die die Option zum Angeben des Auffüllwerts bietet.

  • Center ist das untergeordnete Widget des Container- Widgets. Auch hier ist Text das untergeordnete Element des Center- Widgets. Text wird verwendet, um die Nachricht anzuzeigen, und Center wird verwendet, um die Textnachricht in Bezug auf das übergeordnete Widget Container zu zentrieren .

Das Endergebnis des oben angegebenen Codes ist ein Layoutbeispiel wie unten gezeigt -

Mehrere untergeordnete Widgets

In dieser Kategorie verfügt ein bestimmtes Widget über mehr als ein untergeordnetes Widget, und das Layout jedes Widgets ist eindeutig.

Das Zeilen- Widget ermöglicht beispielsweise das Layout der untergeordneten Elemente in horizontaler Richtung, während das Spalten- Widget das Layout der untergeordneten Elemente in vertikaler Richtung ermöglicht. Durch das Erstellen von Zeilen und Spalten kann ein Widget mit beliebiger Komplexität erstellt werden.

Lassen Sie uns einige der häufig verwendeten Widgets in diesem Abschnitt kennenlernen.

  • Row - Ermöglicht die horizontale Anordnung der Kinder.

  • Column - Ermöglicht die vertikale Anordnung der Kinder.

  • ListView - Ermöglicht das Anordnen der untergeordneten Elemente als Liste.

  • GridView - Ermöglicht die Anordnung seiner Kinder als Galerie.

  • Expanded - Wird verwendet, um die untergeordneten Elemente des Zeilen- und Spalten-Widgets so zu gestalten, dass sie den maximal möglichen Bereich belegen.

  • Table - Tabellenbasiertes Widget.

  • Flow - Flow-basiertes Widget.

  • Stack - Stapelbasiertes Widget.

Erweiterte Layout-Anwendung

In diesem Abschnitt erfahren Sie, wie Sie eine komplexe Benutzeroberfläche für die Produktliste mit benutzerdefiniertem Design erstellen, indem Sie Widgets mit einem oder mehreren untergeordneten Layouts verwenden.

Befolgen Sie zu diesem Zweck die unten angegebene Reihenfolge -

  • Erstellen Sie eine neue Flutter- Anwendung in Android Studio, product_layout_app .

  • Ersetzen Sie den main.dart- Code durch den folgenden Code -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 

class MyApp extends StatelessWidget {
   // This widget is the root of your application.
   @override 
   Widget build(BuildContext context) {
      return MaterialApp( 
         title: 'Flutter Demo', theme: ThemeData( 
         primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page'),
      ); 
   } 
} 
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
      
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),), 
         body: Center(child: Text( 'Hello World', )), 
      ); 
   }
}
  • Here,

  • Wir haben das MyHomePage- Widget erstellt, indem wir StatelessWidget anstelle des Standard- StatefulWidget erweitert und dann den entsprechenden Code entfernt haben.

  • Erstellen Sie nun ein neues Widget, ProductBox, gemäß dem unten angegebenen Design.

  • Der Code für die ProductBox lautet wie folgt.

class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) 
      : super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 

   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), height: 120,  child: Card( 
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[
                  Image.asset("assets/appimages/" +image), Expanded(
                     child: Container(
                        padding: EdgeInsets.all(5), child: Column(
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[ 
                              
                              Text(this.name, style: TextStyle(fontWeight: 
                                 FontWeight.bold)), Text(this.description), 
                              Text("Price: " + this.price.toString()), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}
  • Bitte beachten Sie Folgendes im Code -

  • ProductBox hat vier Argumente verwendet, wie unten angegeben -

    • Name - Produktname

    • Beschreibung - Produktbeschreibung

    • Preis - Preis des Produkts

    • Bild - Bild des Produkts

  • ProductBox verwendet sieben integrierte Widgets, wie unten angegeben -

    • Container
    • Expanded
    • Row
    • Column
    • Card
    • Text
    • Image
  • ProductBox wird mit dem oben genannten Widget entwickelt. Die Anordnung oder Hierarchie des Widgets ist in der folgenden Abbildung angegeben.

  • Platzieren Sie nun ein Dummy-Image (siehe unten) für Produktinformationen im Assets-Ordner der Anwendung und konfigurieren Sie den Assets-Ordner in der Datei pubspec.yaml wie unten gezeigt -

assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png

iPhone.png

Pixel.png

Laptop.png

Tablet.png

Pendrive.png

Floppy.png

Verwenden Sie schließlich das ProductBox- Widget im MyHomePage- Widget wie unten angegeben -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title:Text("Product Listing")), 
         body: ListView(
            shrinkWrap: true, padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget> [
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox(
                  name: "Pixel", 
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
  • Hier haben wir ProductBox als untergeordnete Elemente des ListView- Widgets verwendet.

  • Der vollständige Code (main.dart) der Produktlayoutanwendung (product_layout_app) lautet wie folgt:

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 

class MyApp extends StatelessWidget { 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', theme: ThemeData(
            primarySwatch: Colors.blue,
         ), 
         home: MyHomePage(title: 'Product layout demo home page'), 
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @override 
   Widget build(BuildContext context) { 
      return Scaffold( 
         appBar: AppBar(title: Text("Product Listing")), 
         body: ListView(
            shrinkWrap: true, 
            padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget>[ 
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox( 
                  name: "Pixel",    
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox( 
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) :
      super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 120, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column(    
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(
                                 this.name, style: TextStyle(
                                    fontWeight: FontWeight.bold
                                 )
                              ),
                              Text(this.description), Text(
                                 "Price: " + this.price.toString()
                              ), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}

Die endgültige Ausgabe der Anwendung lautet wie folgt: