在 Flutter 中灵活制作小部件溢出

Posted

技术标签:

【中文标题】在 Flutter 中灵活制作小部件溢出【英文标题】:Flexible making widgets overflow in Flutter 【发布时间】:2021-05-18 10:46:26 【问题描述】:

我正在构建一个 Flutter 网络应用程序,其中我有一个带有 4 个图标按钮和 1 个作为用户配置文件的 MaterialButton 的菜单界面,如下所示: 我使用灵活来确保没有溢出,但是如果我最小化窗口,图标按钮会溢出,如下所示: 有什么办法可以防止这种情况发生吗?这是我的代码:

child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Flexible(
              flex: 2,
              child: IconButton(
                  icon: Icon(
                    Icons.chat_bubble_outline_rounded,
                    color: Colors.white,
                  ),
                  onPressed: null),
            ),
            Flexible(
              flex: 2,
              child: IconButton(
                  icon: Icon(
                    Icons.settings_outlined,
                    color: Colors.white,
                  ),
                  onPressed: null),
            ),
            Flexible(
              flex: 2,
              child: IconButton(
                  icon: Icon(
                    FontAwesomeIcons.wallet,
                    color: Colors.white,
                  ),
                  onPressed: null),
            ),
            Flexible(
              flex: 2,
              child: IconButton(
                  icon: Icon(
                    Icons.notifications_outlined,
                    color: Colors.white,
                  ),
                  onPressed: null),
            ),
            MaterialButton(
              shape: CircleBorder(),
              onPressed: () 
                print('click');
              ,
              child: CircleAvatar(
                backgroundImage: NetworkImage(user.photoURL.toString()),
              ),
            )
          ],
        ),

感谢您的帮助!

【问题讨论】:

【参考方案1】:

我认为 Flexible 不会解决这里的问题。而不是这个,我有两个选择。

1) 用 ListView 替换 Row(也提供 scrollDirection 作为水平)。

这将防止溢出,并且当屏幕调整为更小的宽度时,列表将可滚动。我更喜欢这样做。

2) 相对于屏幕宽度缩放所有按钮。 这将为您提供响应式布局,因为按钮将随着屏幕宽度的变化而调整大小。但是您需要确保它们不会变得太小以至于用户会觉得难以按下它们。

【讨论】:

【参考方案2】:

这是你想要达到的目标吗?

您可以通过SingleChildScrollView 实现此目的。

我将SingleChildScrollViewConstrainedBox 结合起来,以便在屏幕大于需要时散布图标。

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) 
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: ConstrainedBox(
        constraints: BoxConstraints(minWidth: constraints.maxWidth),
        child: Row(...),
      ),
    );
  ,
),

完整的源代码,方便复制粘贴

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main() 
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );


class HomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(width: 800, child: MyBar()),
            const SizedBox(height: 16.0),
            Container(width: 400, child: MyBar()),
            const SizedBox(height: 16.0),
            Container(width: 200, child: MyBar()),
            const SizedBox(height: 16.0),
            Container(
              width: 100,
              child: SingleChildScrollView(child: MyBar()),
            ),
          ],
        ),
      ),
    );
  


class MyBar extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Container(
      padding: EdgeInsets.symmetric(vertical: 8.0),
      color: Colors.amber.shade300,
      child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) 
          return SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: ConstrainedBox(
              constraints: BoxConstraints(
                minWidth: constraints.maxWidth,
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  IconButton(
                      icon: Icon(
                        Icons.chat_bubble_outline_rounded,
                        color: Colors.white,
                      ),
                      onPressed: null),
                  IconButton(
                      icon: Icon(
                        Icons.settings_outlined,
                        color: Colors.white,
                      ),
                      onPressed: null),
                  IconButton(
                      icon: Icon(
                        FontAwesomeIcons.wallet,
                        color: Colors.white,
                      ),
                      onPressed: null),
                  IconButton(
                      icon: Icon(
                        Icons.notifications_outlined,
                        color: Colors.white,
                      ),
                      onPressed: null),
                  MaterialButton(
                    shape: CircleBorder(),
                    onPressed: () 
                      print('click');
                    ,
                    child: CircleAvatar(
                      child: Text('X'),
                    ),
                  )
                ],
              ),
            ),
          );
        ,
      ),
    );
  

【讨论】:

以上是关于在 Flutter 中灵活制作小部件溢出的主要内容,如果未能解决你的问题,请参考以下文章

当文本在 Flutter 中溢出时如何使 Text 小部件像选取框一样

Flutter - 动态小部件定位

Flutter Row 小部件通过切断剩余区域解决 RenderFlex 溢出问题

listview.builder 底部溢出和灵活和扩展小部件的错误

listview.builder底部溢出和使用灵活和扩展小部件的错误

Flutter OverflowBox 在列中的下一个小部件后面