Größe der Elemente auf den Prozentsatz der Bildschirmbreite / -höhe

153

Gibt es eine einfache Möglichkeit (ohne LayoutBuilder), ein Element relativ zur Bildschirmgröße (Breite / Höhe) zu dimensionieren? Beispiel: Wie stelle ich die Breite einer CardView auf 65% der Bildschirmbreite ein?

Es kann build(offensichtlich) nicht innerhalb der Methode durchgeführt werden, daher müsste es bis zum Post-Build verschoben werden. Gibt es einen bevorzugten Ort, um solche Logik zu setzen?

Luke
quelle
Nur zu sagen, das ist im Allgemeinen keine gute Praxis, IMO, das ist Webdesign. In Apps sollten Sie im Allgemeinen Gerätepixel verwenden, um Größen zu definieren, und Paddings verwenden, um Ihre Widgets einzufügen, da Ihr Seitenverhältnis fast immer gleich ist (außer bei Tablets).
Leodriesch
7
Nach weiteren 1,5 Jahren scheint dies doch keine so schlechte Idee zu sein. Jeden Monat kommen neue Telefone mit einem immer seltsameren Seitenverhältnis heraus.
Farid

Antworten:

156

FractionallySizedBoxkann auch nützlich sein. Sie können die Bildschirmbreite auch direkt auslesen MediaQuery.of(context).sizeund darauf basierend eine Box mit Größe erstellen

MediaQuery.of(context).size.width * 0.65

Wenn Sie die Größe wirklich als Bruchteil des Bildschirms festlegen möchten, unabhängig vom Layout.

Ian Hickson
quelle
202

Dies ist eine ergänzende Antwort, die die Implementierung einiger der genannten Lösungen zeigt.

FractionallySizedBox

Wenn Sie ein einzelnes Widget haben, können Sie mithilfe eines FractionallySizedBoxWidgets einen Prozentsatz des verfügbaren zu füllenden Speicherplatzes angeben. Hier wird das Grün Containerso eingestellt, dass es 70% der verfügbaren Breite und 30% der verfügbaren Höhe ausfüllt.

FractionallySizedBox

Widget myWidget() {
  return FractionallySizedBox(
    widthFactor: 0.7,
    heightFactor: 0.3,
    child: Container(
      color: Colors.green,
    ),
  );
}

Erweitert

Mit dem ExpandedWidget kann ein Widget den verfügbaren Platz horizontal ausfüllen, wenn es sich in einer Zeile befindet, oder vertikal, wenn es sich in einer Spalte befindet. Sie können die flexEigenschaft mit mehreren Widgets verwenden, um ihnen Gewichte zu geben. Hier nimmt das Grün Container70% der Breite und das Gelb Container30% der Breite ein.

Erweitert

Wenn Sie es vertikal tun wollen, dann ersetzen Sie einfach Rowmit Column.

Widget myWidget() {
  return Row(
    children: <Widget>[
      Expanded(
        flex: 7,
        child: Container(
          color: Colors.green,
        ),
      ),
      Expanded(
        flex: 3,
        child: Container(
          color: Colors.yellow,
        ),
      ),
    ],
  );
}

Ergänzungscode

Hier ist der main.dartCode als Referenz.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("FractionallySizedBox"),
        ),
        body: myWidget(),
      ),
    );
  }
}

// replace with example code above
Widget myWidget() {
  return ...
}
Suragch
quelle
4
So schreiben Sie eine StackOverflow-Antwort! Danke! Hat mir beim DialogStyling geholfen :)
Aleksandar
116

Dies könnte etwas klarer sein:

double width = MediaQuery.of(context).size.width;

double yourWidth = width * 0.65;

Hoffe das hat dein Problem gelöst.

Keshav Aditya RP
quelle
16

Sie können eine Spalte / Zeile mit flexiblen oder erweiterten untergeordneten Elementen erstellen , deren Flex-Werte sich zu den gewünschten Prozentsätzen addieren.

Möglicherweise ist das AspectRatio- Widget auch hilfreich.

Collin Jackson
quelle
9
MediaQuery.of(context).size.width
Nitin Mehta
quelle
9

Es gibt viele Möglichkeiten, dies zu tun

1. Verwenden von MediaQuery: Der zurückgegebene Vollbildmodus Ihres Geräts, einschließlich Appbar und Symbolleiste

 Container(
        width: MediaQuery.of(context).size.width * 0.50,
        height: MediaQuery.of(context).size.height*0.50, 
        color: Colors.blueAccent[400],
 )

Geben Sie hier die Bildbeschreibung ein


2. Verwenden von Erweitert: Sie können das Verhältnis Breite / Höhe einstellen

 Container(
        height: MediaQuery.of(context).size.height * 0.50,
        child: Row(
          children: <Widget>[
            Expanded(
              flex: 70,
              child: Container(
                color: Colors.lightBlue[400],
              ),
            ),
            Expanded(
              flex: 30,
              child: Container(
                color: Colors.deepPurple[800],
              ),
            )
          ],
        ),
    )

Geben Sie hier die Bildbeschreibung ein



3. Andere mögen Flexible und AspectRatio und FractionallySizedBox

Sanjayrajsinh
quelle
7

Sie können MediaQuery mit dem aktuellen Kontext Ihres Widgets verwenden und danach Breite oder Höhe wie folgt abrufen. double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height Sie können es mit dem gewünschten Prozentsatz multiplizieren

parth jansari
quelle
7

Ermitteln Sie zuerst die Größe des Bildschirms.

Size size = MediaQuery.of(context).size;

Danach können Sie es erhalten widthund mit multiplizieren 0.5, um 50% der Bildschirmbreite zu erhalten.

double width50 = size.width * 0.5;

Aber das Problem tritt im Allgemeinen heightstandardmäßig auf, wenn wir es verwenden

double screenHeight = size.height;

Die Höhe, die wir erhalten, ist die globale Höhe, die StatusBar+ notch+ AppBarHöhe enthält. Um die linke Höhe des Geräts zu erhalten, müssen paddingHöhe ( StatusBar+ notch) und AppBarHöhe von der Gesamthöhe abgezogen werden . So machen wir es.

double abovePadding = MediaQuery.of(context).padding.top;
double appBarHeight = appBar.preferredSize.height;
double leftHeight = screenHeight - abovePadding - appBarHeight;

Jetzt können wir Folgendes verwenden, um 50% unseres Bildschirms in die Höhe zu bringen.

double height50 = leftHeight * 0.5
CopsOnRoad
quelle
3

Wenn Sie GridView verwenden, können Sie so etwas wie die Lösung von Ian Hickson verwenden.

crossAxisCount: MediaQuery.of(context).size.width <= 400.0 ? 3 : MediaQuery.of(context).size.width >= 1000.0 ? 5 : 4
Rody Davis
quelle
2

Verwenden Sie das LayoutBuilder-Widget, das Ihnen Einschränkungen gibt, mit denen Sie die Höhe ermitteln können, die die AppBar und die Auffüllung ausschließt. Verwenden Sie dann eine SizedBox und geben Sie die Breite und Höhe mithilfe der Einschränkungen aus dem LayoutBuilder an

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
Nicolas
quelle