调整元素到屏幕宽度/高度的百分比


153

是否有一种简单的(非LayoutBuilder)方式来相对于屏幕尺寸(宽度/高度)来调整元素的尺寸?例如:如何将CardView的宽度设置为屏幕宽度的65%。

它不能在build方法内部完成(很明显),因此必须推迟到构建后再进行。有没有放置这样的逻辑的首选位置?


只是说,这通常不是IMO的好习惯,这是Web设计的东西。在应用程序中,通常应该使用设备像素来定义大小,并使用填充来插入小部件,因为您的长宽比几乎总是相同的(平板电脑除外)。
leodriesch

7
再过1.5年,看来这毕竟不是一个坏主意。每个月都会有一部新手机问​​世,其怪异度和怪异的长宽比都很高。
Farid

Answers:


156

FractionallySizedBox可能也有用。您也可以直接从屏幕宽度中读取屏幕宽度,MediaQuery.of(context).size并根据该尺寸创建一个尺寸框

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

如果您确实想将大小调整为屏幕的一小部分,而不管布局是什么。


202

这是一个补充性答案,显示了上述两个解决方案的实现。

分数框

如果只有一个窗口小部件,则可以使用FractionallySizedBox窗口小部件指定要填充的可用空间的百分比。在这里,绿色Container设置为填充可用宽度的70%和可用高度的30%。

分数框

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造型:)
Aleksandar

116

这可能更清楚一些:

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

double yourWidth = width * 0.65;

希望这能解决您的问题。




9

有很多方法可以做到这一点

1.使用MediaQuery: 它返回设备的全屏显示,包括appbar,toolbar

 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.其他 诸如FlexibleAspectRatioFractionallySizedBox


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.550%的屏幕宽度。

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,则可以使用Ian Hickson的解决方案。

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,
        ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.