Dopasowywanie elementów do procentowej szerokości / wysokości ekranu


153

Czy istnieje prosty (inny niż LayoutBuilder) sposób określania rozmiaru elementu względem rozmiaru ekranu (szerokość / wysokość)? Na przykład: jak ustawić szerokość CardView na 65% szerokości ekranu.

Nie można tego zrobić wewnątrz buildmetody (oczywiście), więc musiało zostać odłożone do czasu kompilacji. Czy jest jakieś preferowane miejsce na taką logikę?


Mówiąc tylko, to generalnie nie jest dobra praktyka IMO, to jest projektowanie stron internetowych. W aplikacjach należy generalnie używać pikseli urządzenia do definiowania rozmiarów i używać wyściółek do wstawiania widżetów, ponieważ współczynnik proporcji jest prawie zawsze taki sam (z wyjątkiem tabletów).
leodriesch

7
Po kolejnych 1,5 roku wydaje się, że to wcale nie jest taki zły pomysł. Każdego miesiąca pojawiają się nowe telefony o dziwniejszych i dziwniejszych proporcjach.
Farid

Odpowiedzi:


156

FractionallySizedBoxmoże być również przydatne. Możesz także odczytać szerokość ekranu bezpośrednio z MediaQuery.of(context).sizei na tej podstawie utworzyć odpowiednie pole

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

jeśli naprawdę chcesz mieć ułamek ekranu, niezależnie od układu.


202

To jest odpowiedź uzupełniająca pokazująca implementację kilku z wymienionych rozwiązań.

FractionallySizedBox

Jeśli masz pojedynczy widżet, możesz użyć FractionallySizedBoxwidżetu, aby określić procent dostępnego miejsca do wypełnienia. Tutaj zielony Containerjest ustawiony na wypełnienie 70% dostępnej szerokości i 30% dostępnej wysokości.

FractionallySizedBox

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

Rozszerzony

ExpandedWidget pozwala widget wypełnić dostępną przestrzeń, w poziomie, jeśli jest w rzędzie, albo pionowo, gdy znajduje się on w kolumnie. Możesz użyć tej flexwłaściwości z wieloma widżetami, aby nadać im wagi. Tutaj zielony Containerzajmuje 70% szerokości, a żółty Container30% szerokości.

Rozszerzony

Jeśli chcesz to zrobić w pionie, a potem po prostu wymienić Rowsię Column.

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

Kod dodatkowy

Oto main.dartkod w celach informacyjnych.

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 ...
}

4
W ten sposób piszesz odpowiedź StackOverflow! Dziękuję Ci! Pomogła mi w Dialogstylizacji :)
Aleksandar

116

To może być trochę bardziej jasne:

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

double yourWidth = width * 0.65;

Mam nadzieję, że to rozwiązało Twój problem.




9

Można to zrobić na wiele sposobów

1. Korzystanie z MediaQuery: powrót do pełnego ekranu urządzenia, w tym paska aplikacji, paska narzędzi

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

wprowadź opis obrazu tutaj


2. Korzystanie z rozszerzenia: Możesz ustawić stosunek szerokości do wysokości

 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],
              ),
            )
          ],
        ),
    )

wprowadź opis obrazu tutaj



3. Inne, takie jak Flexible i AspectRatio oraz FractionallySizedBox


7

możesz użyć MediaQuery z bieżącym kontekstem twojego widżetu i uzyskać szerokość lub wysokość w ten sposób double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height , możesz pomnożyć go przez żądany procent


7

Najpierw uzyskaj rozmiar ekranu.

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

Po tym możesz go pobrać widthi pomnożyć przez, 0.5aby uzyskać 50% szerokości ekranu.

double width50 = size.width * 0.5;

Ale problem pojawia się na ogół height, domyślnie, gdy używamy

double screenHeight = size.height;

Wysokość, którą otrzymujemy, to wysokość globalna, która obejmuje StatusBar+ notch+ AppBarwysokość. Aby więc uzyskać lewą wysokość urządzenia, musimy odjąć paddingwysokość ( StatusBar+ notch) i AppBarwysokość od całkowitej wysokości. Oto jak to robimy.

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

Teraz możemy użyć następujących, aby uzyskać 50% wysokości naszego ekranu.

double height50 = leftHeight * 0.5

3

jeśli używasz GridView, możesz użyć czegoś takiego jak rozwiązanie Iana Hicksona.

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

2

Użyj widgetu LayoutBuilder, który zapewni ograniczenia, których możesz użyć do uzyskania wysokości, która wyklucza AppBar i wypełnienie. Następnie użyj SizedBox i podaj szerokość i wysokość przy użyciu ograniczeń z LayoutBuilder

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.