简体   繁体   中英

Flutter - How to display a GridView within an SimpleDialog box?

Asked a very similar question yesterday concerning displaying a GridView in an AlertDialog and got the perfect answer for wrapping Widget in a container and adding width. Now I decided a SimpleDialog would be better in order to provide more functionality/customization, ie Search Textfields and multiple action button. I get the desired results when displaying the textfield and IconButton, but when I attempt to add the GridView it errors out. I applied the previous rules but I'm getting similar errors where UI fades but no widget displays. I've tried adding width to different widgets with no luck. Here is my code...

Future<Null> _neverSatisfied() async {
    return showDialog<Null>(
      context: context,
      barrierDismissible: false, // user must tap button!
      child: new SimpleDialog(
        contentPadding: const EdgeInsets.all(10.0),
        title: new Text(
          'CHOOSE YOUR GIF PROFILE IMAGE',
          style: new TextStyle(fontWeight: FontWeight.bold, color: Colors.blue),
          textAlign: TextAlign.center,
        ),
        children: <Widget>[
          new Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    new Padding(padding: new EdgeInsets.all(10.0)),
                    new Expanded(
                        child: new TextField(
                            decoration:
                                new InputDecoration(labelText: "SEARCH GIF'S"),
                            controller: _searchController,
                            onSubmitted: (str) {
                              setState(() {
                                str = _searchController.text;
                              });
                            })),
                    new Padding(padding: new EdgeInsets.all(2.0)),
                    new IconButton(
                      icon: new Icon(
                        Icons.search,
                        color: Colors.blue,
                      ),
                      onPressed: () {
                        print('${_searchController.text}');
                      },
                      highlightColor: Colors.amber,
                      splashColor: Colors.amber,
                      iconSize: 25.0,
                    ),
                  ]),
              new Padding(padding: new EdgeInsets.all(2.0)),

              new Container(
                // Specify some width
                width: MediaQuery.of(context).size.width * .5,
                child: new InkWell(
                  splashColor: Colors.blue,
                  onTap: null,
                  child: new GridView.count(
                      crossAxisCount: 4,
                      childAspectRatio: 1.0,
                      padding: const EdgeInsets.all(4.0),
                      mainAxisSpacing: 4.0,
                      crossAxisSpacing: 4.0,
                      children: <String>[
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                        'http://www.for-example.org/img/main/forexamplelogo.png',
                      ].map((String url) {
                        return new GridTile(
                            child: new Image.network(url, fit: BoxFit.cover, width: 12.0, height: 12.0,));
                      }).toList()),
                )
              ),

              new Padding(padding: new EdgeInsets.all(2.0)),
              new IconButton(
              splashColor: Colors.green,
              icon: new Icon(
                Icons.cancel,
                color: Colors.blue,
              ),
              onPressed: () {
                Navigator.of(context).pop();
              })
            ],
          ),
        ],
      ),
    );
  }

Here is my Error log...

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ The following assertion was thrown during performLayout(): RenderViewport does not support returning intrinsic dimensions. Calculating the intrinsic dimensions would require instantiating every child of the viewport, which defeats the point of viewports being lazy. If you are merely trying to shrink-wrap the viewport in the main axis direction, consider a RenderShrinkWrappingViewport render object (ShrinkWrappingViewport widget), which achieves that effect without implementing the intrinsic dimension API.

That error essentially means that there is a scroll region or a widget that can grow, and you're trying to put another scroll region inside it without specifying how big the inner scroll region should be. When flutter attempts to calculate the size of various things, it can't because there are two different things that can grow/shrink; in particular the vertical direction of the grid is the problem in your case. If the gridview calculated the size of all of its children, it could then sort out all the rest of the sizes according to that (as the error message says). But the whole point of gridview it to display a large amount of data that most likely scrolls off the screen, and so if it were to do that calculation it could slow things down in the normal case of using gridview.

I'd bet that AlertDialog has a constraint for height and/or doesn't scroll, and that's why you didn't see a problem for it.

To fix your problem, you have two options. If you are going to have a large amount of items (it'd help me answering if you described what you were actually trying to make), keep using the gridview but simply assign a height as well it to the container it's in. That way the dialog can size itself happily knowing the height of all of its children, and the grid can size itself within the height you've given (TBH I'm not sure if you even need width defined any more).

The other option, if you don't have a large amount of items (ie they will more or less fit on the screen and/or you don't want them to scroll), use a wrap instead of a grid which will directly layout all of your items. This has the advantage that it will lay everything out nicely when your orientation changes as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM