Flutter:SimpleDialog中的ListView

Dar*_*han 16 listview flutter

我想在我的Flutter应用程序中使用以下代码显示带有ListView.builder的SimpleDialog:

showDialog(
  context: context,
  builder: (BuildContext context) {
    return new SimpleDialog(
      children: <Widget>[
        new FittedBox(
          child: new ListView(
            children: <Widget>[
              new Text("one"),
              new Text("two"),
            ],
          ),
        )
      ],
    );
  },
);
Run Code Online (Sandbox Code Playgroud)

这给出了这个错误(抱歉,我无法将日志包装为代码,因为Stackoverflow抱怨代码太多了):

══╡通过渲染图书馆的例外情况╞═​​══════════════════════════════════════════════════════════════════════════════════════════════ =/flutter(4481):在performLayout()期间抛出以下断言:I/flutter(4481):RenderViewport不支持返回内部维度.I/flutter(4481):计算内在维度需要实例化视口的每个子节点,我/ flutter(4481):击败视口的懒惰点.I/flutter(4481):如果你只是想在主轴方向上收缩包装视口,可以考虑一个I/flutter(4481):RenderShrinkWrappingViewport渲染对象(ShrinkWrappingViewport小部件),它实现了I/flutter(4481) :没有实现内在维度API的效果.I/flutter(4481):...我/ flutter(4481):抛出了另一个异常:RenderBox没有布局:RenderPhysicalShape#83d92 relayoutBoundary = up2 NEEDS-PAINT I/flutter(4481):抛出另一个异常:' package:flutter/src/rendering/shifted_box.dart':断言失败:第310行pos 12:'child.hasSize':不是真的.I/flutter(4481):抛出了另一个异常:RenderBox没有布局:RenderPhysicalShape#83d92 relayoutBoundary = up2

我尝试使用具有特定高度和宽度的Container,它可以工作,但我希望ListView能够适应Dialog.

如何在SimpleDialog中包含ListView?

Gov*_*iyo 14

只是包装ListView.builderContainer一个特定的高度宽度

Widget setupAlertDialoadContainer() {
    return Container(
      height: 300.0, // Change as per your requirement
      width: 300.0, // Change as per your requirement
      child: ListView.builder(
        shrinkWrap: true,
        itemCount: 5,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('Gujarat, India'),
          );
        },
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

并在showDialog中调用上述方法。

showDialog(
   context: context,
   builder: (BuildContext context) {
   return AlertDialog(
       title: Text('Country List'),
       content: getAllSelectedCountry(),
   );
  }
);
Run Code Online (Sandbox Code Playgroud)

编辑:

您也可以接受@Rap的评论。

  • 我只需要高度 * 或 * 宽度,而不是两者。 (4认同)
  • 我需要同时填充高度和宽度吗?这是为什么?@说唱 (2认同)
  • 我也需要两者。 (2认同)

Use*_*ser 10

添加width: double.maxFinitecontainer解决了我的问题。

 @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Sample Dialog'),
      content: Container(
        width: double.maxFinite,
        child: ListView(
          children: <Widget>[
            Text('Item 1'),
            Text('Item 2'),
          ],
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)


Sur*_*gch 7

对于将来的访问者来说,这是一个更一般的答案。

如何用列表创建对话框

如果要使用ListView进行对话框,则应考虑使用SimpleDialog。SimpleDialog旨在显示列表中的选项(与AlertDialog相反,后者旨在通知用户某些内容)。

这是一个简单的示例:

在此处输入图片说明

创建SimpleDialog的过程基本上与AlertDialog相同(它们都基于Dialog),只是您定义了名为SimpleDialogOptions而不是按钮的列表项小部件。当按下列表选项时,将触发您可以响应的回调。

  // set up the list options
  Widget optionOne = SimpleDialogOption(
    child: const Text('horse'),
    onPressed: () {},
  );
  Widget optionTwo = SimpleDialogOption(
    child: const Text('cow'),
    onPressed: () {},
  );
  Widget optionThree = SimpleDialogOption(
    child: const Text('camel'),
    onPressed: () {},
  );
  Widget optionFour = SimpleDialogOption(
    child: const Text('sheep'),
    onPressed: () {},
  );
  Widget optionFive = SimpleDialogOption(
    child: const Text('goat'),
    onPressed: () {},
  );

  // set up the SimpleDialog
  SimpleDialog dialog = SimpleDialog(
    title: const Text('Choose an animal'),
    children: <Widget>[
      optionOne,
      optionTwo,
      optionThree,
      optionFour,
      optionFive,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return dialog;
    },
  );
Run Code Online (Sandbox Code Playgroud)

处理选件压力

当用户单击一个项目时,您可以关闭对话框并执行一些操作。

  Widget optionOne = SimpleDialogOption(
    child: const Text('horse'),
    onPressed: () {
      Navigator.of(context).pop();
      _doSomething();
    },
  );
Run Code Online (Sandbox Code Playgroud)

笔记

这是上面示例的完整代码。

主镖

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SimpleDialog',
      home: Scaffold(
          appBar: AppBar(
            title: Text('SimpleDialog'),
          ),
          body: MyLayout()),
    );
  }
}

class MyLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: RaisedButton(
        child: Text('Show alert'),
        onPressed: () {
          showAlertDialog(context);
        },
      ),
    );
  }
}

// replace this function with the examples above
showAlertDialog(BuildContext context) {

  // set up the list options
  Widget optionOne = SimpleDialogOption(
    child: const Text('horse'),
    onPressed: () {
      print('horse');
      Navigator.of(context).pop();
    },
  );
  Widget optionTwo = SimpleDialogOption(
    child: const Text('cow'),
    onPressed: () {
      print('cow');
      Navigator.of(context).pop();
    },
  );
  Widget optionThree = SimpleDialogOption(
    child: const Text('camel'),
    onPressed: () {
      print('camel');
      Navigator.of(context).pop();
    },
  );
  Widget optionFour = SimpleDialogOption(
    child: const Text('sheep'),
    onPressed: () {
      print('sheep');
      Navigator.of(context).pop();
    },
  );
  Widget optionFive = SimpleDialogOption(
    child: const Text('goat'),
    onPressed: () {
      print('goat');
      Navigator.of(context).pop();
    },
  );

  // set up the SimpleDialog
  SimpleDialog dialog = SimpleDialog(
    title: const Text('Choose an animal'),
    children: <Widget>[
      optionOne,
      optionTwo,
      optionThree,
      optionFour,
      optionFive,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return dialog;
    },
  );
}
Run Code Online (Sandbox Code Playgroud)

  • @Emen:您可以使用`Navigator.of(context).pop();`关闭对话框 (2认同)

Jos*_*Jet 5

将ListView包裹在容器中并为其设置宽度:double.maxFinite,可解决iOS / Android在对话框中无法使用ListView的问题:

showDialog(
   context: context,
   builder: (BuildContext context) {
      return AlertDialog(
         content: Container(
            width: double.maxFinite,
            child: ListView(
               children: <Widget>[]
            ),
         ),
      );
   }
);
Run Code Online (Sandbox Code Playgroud)

对于在AlertDialog内的Column内的ListView:

showDialog(
   context: context,
   builder: (BuildContext context) {
      return AlertDialog(
         content: Container(
            width: double.maxFinite,
            child: Column(
               mainAxisSize: MainAxisSize.min,
               children: <Widget>[
                  Expanded(
                     ListView(
                        shrinkWrap: true,
                        children: <Widget>[]
                     )
                  )
               ]
            ),
         ),
      );
   }
);
Run Code Online (Sandbox Code Playgroud)

  • 在列上方添加“Container(width:double.maxFinite,wrapper”可以解决问题。似乎没有此功能的对话框仅适用于新的Android版本,例如9.0。 (2认同)