Flutter: ListView in a SimpleDialog

后端 未结 9 1631
深忆病人
深忆病人 2020-12-24 01:04

I want to show a SimpleDialog with ListView.builder in my Flutter app with this code:

showDialog(
  context: context,
  builder: (BuildContext context) {
           


        
相关标签:
9条回答
  • 2020-12-24 01:36

    SImply in the content we need to use a Container with fixed height and width. and the use ListView as a child of Container.

     scrollDialogFunction(){
            return showDialog(
                context: context,
                builder: (BuildContext context) {
                  return AlertDialog(
                    title: Text('List of Index'),
                    content: Container(
                      width: 350.0,
                      height: 250,// Change as per your requirement
                      child: ListView.builder(
                        itemCount: 150,
                        itemBuilder: (BuildContext context, int index) {
                          return ListTile(
                            title: Text(index.toString()),
                          );
                        },
                      ),
                    ),
                    actions: [Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text("ok",style: TextStyle(fontSize: 18),),
                    )],
                  );
                });
          }
    
    0 讨论(0)
  • 2020-12-24 01:37

    Just wrap ListView.builder in a Container with a specific height and width.

    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'),
            );
          },
        ),
      );
    }
    

    And call the above method in showDialog.

    showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text('Country List'),
            content: setupAlertDialoadContainer(),
          );
        });
    

    EDITED:

    You can go with @Rap's comment too.

    0 讨论(0)
  • 2020-12-24 01:41

    I found a way... Although it's a bit hacky, and so there may be a better option.

    You'll need this package:

    import 'package:flutter/services.dart';
    

    Create the widget:

    class MyDialog extends StatefulWidget {
      MyDialog ({Key key}) : super(key: key);
      MyDialogState createState() => new MyDialogState();
    }
    class MyDialogState extends State<MyDialog> {
    

    If the screen rotates it screws things up because the dialog maintains it's original size. You can probably fix that with a bit of effort, but I just lock it to prevent rotating, like this:

      @override
      initState() { super.initState();
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp,
          DeviceOrientation.portraitDown,
        ]);
      }
    

    Then I unlock it like this at the end:

      @override
      dispose() { super.dispose();
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.landscapeRight,
          DeviceOrientation.landscapeLeft,
          DeviceOrientation.portraitUp,
          DeviceOrientation.portraitDown,
        ]);
      }
    

    So that stops the dialog from screwing up. Then I get the size and width of the screen in the build method:

    @override
    Widget build(BuildContext context) {
      double width = MediaQuery.of(context).size.width;
      double height = MediaQuery.of(context).size.height;
    

    Then followed with this layout:

     return ConstrainedBox(
        constraints: BoxConstraints(maxHeight: height, maxWidth: width),
        child: Column(
          children: <Widget>[
            Expanded(
              child: GridView.count(
                primary: false,
                padding: const EdgeInsets.all(20.0),
                crossAxisSpacing: 10.0,
                crossAxisCount: 3,
                children: _images
              )
            ),
          ]
        ),
      );
    }
    

    ..again, I don't think it's the best, but it's been working for me so far.

    0 讨论(0)
  • 2020-12-24 01:42
    showDialog(context: parentcontext,
        builder: (context){
          return SimpleDialog(
            title: Text('create post'),
            children: <Widget>[
              SimpleDialogOption(
                onPressed: handleImageTaking,
                child: Text('take a pic'),
              ),
              SimpleDialogOption(
                onPressed: handleImageSelecting,
                child: Text('select a pic'),
              ),
              SimpleDialogOption(
                child: Text('cancel'),
                onPressed: (){
                  Navigator.pop(context);
                },
              )
            ],
          );
        });
    
    0 讨论(0)
  • 2020-12-24 01:44

    This is a more general answer for future visitors.

    How to create a dialog with a list

    If you want a dialog with a ListView, you should consider a SimpleDialog. A SimpleDialog is designed to show options in a list (as opposed to an AlertDialog, which is meant to notify the user of something).

    Here is a simple example:

    The process of creating a SimpleDialog is basically the same as for an AlertDialog (they are both based on Dialog), except that you define list item widgets called SimpleDialogOptions instead of buttons. When a list option is pressed a callback is fired that you can respond to.

      // 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;
        },
      );
    

    Handling option presses

    When a user clicks an item you can close the dialog an perform some action.

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

    Notes

    • The documentation recommends using a switch to return an enum as a Future.
    • See also How to make an AlertDialog in Flutter?

    Code

    Here is the full code for the example above.

    main.dart

    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;
        },
      );
    }
    
    0 讨论(0)
  • 2020-12-24 01:46

    Used SingleChildScrollView with physics: NeverScrollableScrollPhysics() and shrinkWrap: true in your ListView

      showDialog(
          context: context,
          builder: (_) {
            return AlertDialog(
              title: widget,
              content: SingleChildScrollView( //MUST TO ADDED
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    ...//any widgets,
                    ListView.builder(
                        shrinkWrap: true, //MUST TO ADDED
                        physics: NeverScrollableScrollPhysics(), //MUST TO ADDED
                        itemCount: model.length,
                        itemBuilder: (BuildContext c, int index) {
                          return ListTile();
                        })
                  ],
                ),
              ),
            );
          },
        );
    
    0 讨论(0)
提交回复
热议问题