Flutter-自动调整大小AlertDialog以适合列表内容

use*_*216 3 size listview android-alertdialog flutter

我需要从其余Web服务动态加载列表城市,并让用户从警报对话框中选择一个城市。我的代码:

createDialog() {

    fetchCities().then((response) {

      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Wybierz miasto'),
              content: Container(
                height: 200.0,
                width: 400.0,
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: response.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(response[index].name),
                      onTap: () => citySelected(response[index].id),
                    );
                  },
                ),
              ),
            );
          }
      );
    });
  }
Run Code Online (Sandbox Code Playgroud)

结果-对话框始终为200x400,即使只有2个城市可用,底部仍留有不必要的空间:

在此处输入图片说明

如何使对话框的宽度/高度适合实际项目的大小?如果省略heightwidth参数,则会出现异常,并且不会显示任何对话框。在本机Android Java中,我不需要指定任何尺寸,因为对话框本身会自动调整大小。

如何修复我的代码以正确设置对话框大小?请注意,我不知道项目数,它是动态的。

[编辑]

如建议的那样,我用列包装内容:

createDialog() {
    fetchCities().then((response) {
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Wybierz miasto'),
              content: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Container(
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: response.length,
                        itemBuilder: (BuildContext context, int index) {
                          return ListTile(
                            title: Text(response[index].name),
                            onTap: () => citySelected(response[index].id),
                          );
                        },
                      ),
                    )
                  ]
              ),
            );
          }
      );
    });
  }
Run Code Online (Sandbox Code Playgroud)

结果-异常:

I /颤振(5917):??? 渲染库导致的例外情况??????????????????????????????????????????????????? ????????????? I / flutter(5917):在performLayout()期间引发了以下断言:I / flutter(5917):RenderViewport不支持返回固有尺寸。I / flutter(5917):计算固有尺寸将需要实例化视口的每个子级,而I / flutter(5917):消除了视口懒惰的观点。

要测试的通用代码:

showDialog(
       context: context,
       builder: (BuildContext context) {
         return AlertDialog(
           title: Text('Select city'),
           content: Column(
               mainAxisSize: MainAxisSize.min,
               children: <Widget>[
                 Container(
                   child: ListView.builder(
                     shrinkWrap: true,
                     itemCount: 2,
                     itemBuilder: (BuildContext context, int index) {
                       return ListTile(
                         title: Text("City"),
                         onTap: () => {},
                       );
                     },
                   ),
                 )
               ]
           ),
         );
       }
   );
Run Code Online (Sandbox Code Playgroud)

小智 56

我知道现在已经很晚了,但是您尝试过吗?

Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
       Container(
         child: ListView.builder(
           shrinkWrap: true,
           ...
         ),
       )
    ],
);
Run Code Online (Sandbox Code Playgroud)

  • 哇!这是非常简单的解决方案,添加 mainAxisSize: MainAxisSize.min 就足够了 (2认同)

小智 12

我有一个类似的问题。我通过添加修复它:scrollable: true在 AlertDialog

更新的代码将是:

 createDialog() {
    fetchCities().then((response) {
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              scrollable: true,
              title: Text('Wybierz miasto'),
              content: Container(
                height: 200.0,
                width: 400.0,
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: response.length,
                  itemBuilder: (BuildContext context, int index) {
                    return ListTile(
                      title: Text(response[index].name),
                      onTap: () => citySelected(response[index].id),
                    );
                  },
                ),
              ),
            );
          }
      );
    });
  }
Run Code Online (Sandbox Code Playgroud)


Fel*_*lta 11

你的包裹ContainerColumn,在内容paramenter,它的内部,设置mainAxisSize.min在列属性

  • 成功了!`Column( mainAxisSize: MainAxisSize.min, Children: &lt;Widget&gt;[ //list ], );` (3认同)

Cop*_*oad 8

不要mainAxisSize.min在您Column的内容中设置否则如果内容长于视口,您可能会遇到溢出错误。要解决此问题,请使用其中一种方法。

1.裹ColumnSingleChildScrollView

AlertDialog(
  content: SingleChildScrollView( 
    child: Column(
      children: [...],
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

2.使用shrinkWrap: trueListView

AlertDialog(
  content: ListView(
    shrinkWrap: true,
    children: [...],
  ),
)
Run Code Online (Sandbox Code Playgroud)


Pan*_*rld 5

你可以看看SimpleDialog是怎么做的。

Widget dialogChild = IntrinsicWidth(
  stepWidth: 56.0,
  child: ConstrainedBox(
    constraints: const BoxConstraints(minWidth: 280.0),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        if (title != null)
          Padding(
            padding: titlePadding,
            child: DefaultTextStyle(
              style: theme.textTheme.title,
              child: Semantics(namesRoute: true, child: title),
            ),
          ),
        if (children != null)
          Flexible(
            child: SingleChildScrollView(
              padding: contentPadding,
              child: ListBody(children: children),
            ),
          ),
      ],
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)


Asq*_*e17 5

不要使用像 listView 这样的惰性视口并用 SingleChildScrollView 包裹列

AlertDialog 尝试使用其子级的固有尺寸来调整自身大小,而使用惰性视口的小部件(例如 ListView、GridView 和 CustomScrollView)将不起作用。考虑对大内容使用滚动小部件,例如 SingleChildScrollView,以避免溢出。在这里阅读更多内容!

所以你有这样的东西

SingleChildScrollView(          
   child: Column(
      mainAxisSize: MainAxisSize.min,
        children: <Widget>[
           Container(
             child: ListView.builder(
               shrinkWrap: true,
           ...
         ),
       )
    ],
);
Run Code Online (Sandbox Code Playgroud)