Flutter OrientationBuilder LayoutBuilder

Wenn wir eine App programmieren, können wir nicht wissen, auf welchem Smartphone unsere App letztendlich benutzt wird. Natürlich können wir die App für ein bestimmtes Model konzipieren und noch weitere Vorgaben machen, die wahr sein müssen, damit unser Code fehlerfrei läuft. Aber wer schränkt schon gerne den potenziellen Benutzerkreis ohne triftigen Grund ein ?

In diesem Blog hatten wir schon einen Post über MediaQuery.of. Mit ihrer Hilfe erhalten wir Informationen, über das Gerät, auf welchem unser Code läuft.


MediaQuery.of


MediaQuery.of stellt uns verschiedene nützliche Informationen zur Verfügung. Wer im übrigen mehr wissen möchte zu diesem Thema schaut auf dieser Seite für Android und hier für iOS. In diesem Demo Code lesen wir Höhe und Breite aus:


class EinDemo extends StatelessWidget {
  
  int screenHoehe=0;
  int screenBreite=0;

  final String title;

   EinDemo({Key key, this.title}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {

    this.screenHoehe = MediaQuery.of(context).size.height.round();
    this.screenBreite = MediaQuery.of(context).size.width.round();
    
    String text1 =screenBreite.toString();
    String text2 =screenHoehe.toString();

    return Container(
       child: Text("$text1 $text2"),  
    );
  }
}

Mit round() runden wir die double Werte und wandeln sie in Integer Werte um, die wir anschliessend auf den Bildschirm drucken. Wobei das dient eigentlich ja nur der Demonstration..

Sobald man die Höhe und Breite, also die Dimensionen des Bildschirms hat, kann man damit arbeiten. Das nächste das wir wissen sollten: In was für einer Lage befindet sich unser Zielgerät bzw. welche Orientierung herrscht vor. Mit MediaQuery.of(context).orientation erhalten wir auch dazu die entsprechende Antwort. Mit folgendem Beispielcode zeichnen wir je nach Orientierung einen Container(...) auf den Screen. Dazu verwenden wir das OrientationBuilder Widget.

OrientationBuilder



class EinDemo extends StatelessWidget {
 

  final String title;

   EinDemo({Key key, this.title}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {


    return Scaffold(
      appBar: AppBar(
        title:Text(title),
      ),
    body: OrientationBuilder(
      builder: (BuildContext context, Orientation orientation) {
        return Container(
          color: orientation==Orientation.portrait?Colors.orange:Colors.purple,
          width: orientation==Orientation.portrait?200.0:400.0,
          height: orientation==Orientation.portrait?400.0:200.0,
          child: Text("Hallo"),
        );
      },
    ),
    );
  }
}

Das Widget ermöglicht auf einfache Art die Orientierung des Bildschirms mit in den Code einfließen zu lassen. Die Flutter Entwickler haben auch ein gutes Beispiel für einen GridView in diesem Zusammenhang.

LayoutBuilder


Wir haben also Höhe, Breite und Orientierung. All diese Informationen beziehen sich auf das Gerät, nicht aber auf ein Widget. Was aber, wenn unsere Widget Struktur verschachtelt ist und wir zu einem späteren Zeitpunkt, basierend auf einem Eltern Widget, ein Folge Widget implementieren müssen ?

Um hier auch ein Missverständnis zu vermeiden, es gibt für einige Problemstellungen nicht nur eine Lösung. Die Aufgabe ist viel mehr die möglichst beste Lösung zu finden.

Das LayoutBuilder Widget arbeitet mit den BoxConstraints. Vereinfacht ausgedrückt, beschreiben die BoxConstraints die Eckwerte eines Quadrats, wie Höhe und Breite und die entsprechenden Minimum und Maximum Werte. Es ist logisch das wenn die min. und max. Werte für z.b. die Höhe nicht identisch sind, die entsprechende Box flexible dargestellt werden könnte. Die Basis des LayoutBuilder Widgets ist einfach:


LayoutBuilder(
    builder: (context, constraints) {

    },
)

Dieses Widget erwartet, das wir, wie bei OrientationBuilder, eine builder: Funktion implementieren.
Wie oft in Flutter übergeben wir den context an diese Funktion und explizit die BoxConstraints des Eltern Widgets. Wir haben nun Zugriff auf diverse Informationen:


constraints.maxWidth; // die maximale Breite
constraints.maxHeight; // die maximale Höhe
constraints.minWidth; // die mindest Breite
constraints.minHeight; // die mindest Höhe

Diese Informationen können wir nun natürlich weiterverwenden, zum Beispiel:


class EinDemo extends StatelessWidget {
 

  final String title;

   EinDemo({Key key, this.title}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {


    return Scaffold(
      appBar: AppBar(
        title:Text(title),
      ),
    body: LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        if (constraints.maxHeight>constraints.maxWidth) {
          return Container(
           color: Colors.lightGreen,
          );
        } else {
          return Container(
            color: Colors.redAccent,
          );
        }
      },
    ),
    );
  }

Im sehr einfachen Beispiel oben, ändert sich die Farbe, je nach Lage des Geräts (Landscape / Portrait).

Fazit: Flutter bietet bequeme Möglichkeiten flexibel auf  die Eckwerte des Geräts einzugehen, auf welchem unsere App läuft. Das können wir nutzen oder auch nicht. Diese Entscheidung fällt der Entwickler.

Kommentare

  1. Dies ist ein guter Beitrag. Dieser Beitrag gibt wirklich hochwertige Informationen. Ich werde mich auf jeden Fall darum kümmern. Hier finden Sie wirklich sehr nützliche Tipps. Ich danke dir sehr. Mach weiter so

    flutter app

    AntwortenLöschen

Kommentar veröffentlichen

Beliebte Posts aus diesem Blog

Flutter -- ohne Dart geht es nicht 2 -- einfache Variablen Typen

Material Design in Flutter Teil 2

Dart Final Const