如何在Flutter中自动调整图标大小以尽可能大?

35

目前,我正在使用以下代码:

   body: new Container(
            child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
              new MaterialButton(
                height: 120.0,
                child: new Column(
                  children: <Widget>[
                    new Icon(
                      Icons.av_timer,
                      size: 100.0,
                    ),
                    new Text('TIMER'),
                  ],
                ),
                onPressed: null,
              ),
              new MaterialButton(
                height: 120.0,
                child: new Column(
                  children: <Widget>[
                    new Icon(Icons.alarm_add, size: 100.0),
                    new Text('ALARM'),
                  ],
                ),
                onPressed: null,
              )
            ])));

然而,我已经不得不“硬编码”图标大小为100.0和MaterialButton的高度为120.0。

我希望MaterialButton尽可能占据空间(每个屏幕的50%),并且我希望图标能够在该空间内“适当地适应”,最好还能随着文本一起缩放。

目前我还没有在Flutter中找到实现这一点的方法。如果尝试做这件事不是一个好主意(我希望它在任何设备上都可以使用整个屏幕空间),请告诉我原因?

5个回答

50

您可以使用LayoutBuilder在构建期间动态获取父级大小。

一个可行的例子:

fit icon

void main() {
  runApp(new MaterialApp(
    home: new TestIcon(),
  ));
}

class TestIcon extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.white,
      child: new LayoutBuilder(builder: (context, constraint) {
        return new Icon(Icons.access_alarms, size: constraint.biggest.height);
      }),
    );
  }
}

很好 - 如何使用IconButton。 - Gerry

21

截图:

enter image description here


使用 FittedBox

SizedBox.fromSize(
  size: Size.fromRadius(200),
  child: FittedBox(
    child: Icon(Icons.add),
  ),
)

4

在改进了@CopsOnRoad的答案后,我建议使用FittedBoxSizedBox.expand,如下所示:

SizedBox.expand(
    child: FittedBox(
        child: Icon(Icons.add),
    ),
)

这对我在 Stack widget 内部起作用。 - Shoeb Surve

4
关于文字大小,我找不到比基于最大可用高度的某种比率更好的方法。
我还没有发表评论的权利,所以我会在这里发表: 您可以使用最大高度和最大宽度之间的最小值。
它将执行类似于BoxFit.contain的操作。

boxfit


我不确定如何在fontSizeFactor中使用它? - Jackpap
import "dart:math";然后fontSizeFactor: min(constraint.biggest.height, constraint.biggest.width) / 30.0但这大多是为了图标而设置的。因为在Flutter中,尺寸使用DPI(每英寸像素密度)而不是原始像素。因此,无论设备如何,fontsSizeFactor的大小都将相同。 没有必要手动缩放文本大小。 - Rémi Rousselet

0
感谢Darky,我最终使用了LayoutBuilder,以及Expanded Widget、Column Widget和flex参数来给出正确的比例。至于文本大小,我找不到比基于可用最大高度的某种比率更好的方法。
body: new Container(
            child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
              new Expanded(
                  child: new MaterialButton(
                      child: new Column(
                        children: <Widget>[
                          new Expanded(
                            flex: 4,
                            child: new LayoutBuilder(
                                builder: (context, constraint) {
                              return new Icon(
                                Icons.timer,
                                size: constraint.biggest.height,
                              );
                            }),
                          ),
                          new Expanded(child:
                              new LayoutBuilder(builder: (context, constraint) {
                            return new Text('TIMER',
                                style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: constraint.biggest.height/30.0));
                          })),
                        ],
                      ),
                      onPressed: () {
                        showTimePicker(
                          context: context,
                          initialTime: new TimeOfDay.now(),
                        );
                      })),
              new Expanded(
                  child: new MaterialButton(
                      child: new Column(
                        children: <Widget>[
                          new Expanded(
                            flex: 4,
                            child: new LayoutBuilder(
                                builder: (context, constraint) {
                                  return new Icon(
                                    Icons.alarm,
                                    size: constraint.biggest.height,
                                  );
                                }),
                          ),
                          new Expanded(child:
                          new LayoutBuilder(builder: (context, constraint) {
                            return new Text('ALARM',
                                style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: constraint.biggest.height/30.0));
                          })),
                        ],
                      ),
                      onPressed: () {
                        showTimePicker(
                          context: context,
                          initialTime: new TimeOfDay.now(),
                        );
                      })),
            ]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接