Розміщення елементів до відсотка ширини / висоти екрану


153

Чи існує простий (не LayoutBuilder) спосіб розміщення елемента відносно розміру екрана (ширина / висота)? Наприклад: як встановити ширину CardView 65% від ширини екрана.

Це не може бути зроблено всередині buildметоду (очевидно), тому його доведеться відкладати до створення збірки. Чи є переважне місце для такої логіки?


Просто кажучи, це, як правило, не належна практика ІМО, це речі для веб-дизайну. У додатках, як правило, слід використовувати пікселі пристрою для визначення розмірів і використовувати вкладки для вставки віджетів, оскільки співвідношення сторін майже завжди однакове (крім планшетів).
leodriesch

7
Ще через півтора роки, здається, це не така вже й погана ідея. Щомісяця з’являються нові телефони, які мають більш привабливе та дивне співвідношення сторін.
Фарид

Відповіді:


156

FractionallySizedBoxтакож може бути корисним. Ви також можете зчитувати ширину екрана безпосередньо з MediaQuery.of(context).sizeта створювати розмір вікна на основі цього

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

якщо ви дійсно хочете розміру розміру як частину екрану, незалежно від того, яка компонування.


202

Це додаткова відповідь, що показує реалізацію пари згаданих рішень.

ДробоворозмірнийBox

Якщо у вас є один віджет, ви можете використовувати FractionallySizedBoxвіджет, щоб вказати відсоток наявного місця для заповнення. Тут зелена Containerвстановлена ​​для заповнення 70% доступної ширини та 30% наявної висоти.

ДробоворозмірнийBox

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

Розширено

ExpandedВіджет дозволяє віджет , щоб заповнити обсяг пам'яті, доступний, в горизонтальному напрямку, якщо він знаходиться в ряді, або вертикально , якщо він знаходиться в колонці. Ви можете використовувати flexмайно з кількома віджетами, щоб надати їм ваги. Тут зелений Containerзаймає 70% ширини, а жовтий Containerзаймає 30% ширини.

Розширено

Якщо ви хочете зробити це вертикально, то просто замініть Rowна Column.

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

Додатковий код

Ось main.dartкод для вашої довідки.

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
Ось так ви пишете відповідь StackOverflow! Спасибі! Допоміг мені моїм Dialogстайлінгу :)
Олександр

116

Це може бути трохи більш зрозуміло:

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

double yourWidth = width * 0.65;

Сподіваюся, це вирішило вашу проблему.




9

Існує багато способів зробити це

1. Використання MediaQuery: повернення повного екрану вашого пристрою, включаючи панель програм, панель інструментів

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

введіть тут опис зображення


2. Використання розширеного: Ви можете встановити співвідношення ширини / висоти

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

введіть тут опис зображення



3. Інші Як гнучкі і AspectRatio і FractionallySizedBox


7

ви можете використовувати MediaQuery з поточним контекстом віджета і отримувати ширину чи висоту double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height після цього, ви можете помножити його на потрібний відсоток


7

Спочатку отримайте розмір екрану.

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

Після цього ви можете отримати widthі помножити його, 0.5щоб отримати 50% ширини екрана.

double width50 = size.width * 0.5;

Але проблема, як правило, виникає heightза замовчуванням, коли ми використовуємо

double screenHeight = size.height;

Висота, яку ми отримуємо, - це глобальна висота, яка включає StatusBar+ notch+ AppBarвисоту. Отже, щоб отримати ліву висоту пристрою, нам потрібно відняти paddingвисоту ( StatusBar+ notch) і AppBarвисоту від загальної висоти. Ось як ми це робимо.

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

Тепер ми можемо використовувати наступні, щоб отримати 50% нашого екрану у висоту.

double height50 = leftHeight * 0.5

3

якщо ви використовуєте GridView, ви можете використовувати щось на зразок рішення Іна Хіксона.

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

2

Використовуйте віджет LayoutBuilder, який дасть вам обмеження, які ви можете використовувати для отримання висоти, що виключає AppBar та прокладку. Потім використовуйте SizedBox і вкажіть ширину і висоту, використовуючи обмеження LayoutBuilder

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.