Andrii Turkovskyi
Andrii Turkovskyi

Reputation: 29468

How to constrain height of AlertDialog

I show dialog with list inside it.

    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text(select_conference),
            content: ListView.separated(
              itemCount: selected.length,
              separatorBuilder: (context, index) => CommonDivider(),
              itemBuilder: (context, index) => ListTile(...),
            ),
          );
        });

But no matter how many elements is has - dialog fills all available height. Is there any solution to solve this without calculating height of list elements?

Upvotes: 16

Views: 22572

Answers (5)

David
David

Reputation: 11

Wrapping the AlertDialog with a ConstrainedBox widget didn't work for me on its own (perhaps due to changes to Flutter since Rémi Rousselet's answer or because my use case doesn't involve scrolling or because I have other widgets nested in between showDialog and AlertDialog).

As far as I can tell the ConstrainedBox widget needs to be surrounded by a widget that allows it to be smaller than the screen, otherwise ConstrainedBox will just fill the whole screen.

The solution is to wrap ConstrainedBox with another widget that tells it how to layout, e.g., you can simply use Center for this.

Additionally, by default AlertDialog has a padding around it so that it doesn't go all the way to the screen's edges. While this is desirable in many cases, it also means that the actual dialog will be smaller than the maximum size you set in ConstraintBox due to this padding. To account for this, you can set the AlertDialog's insetPadding attribute to zero and then use a Padding widget around the ConstrainedBox widget to add this padding manually (see code below).

My full code is as follows:

  await showDialog<void>(
    context: context,
    builder: (context) {
      /* ... */
      return Center(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0), // <- this is the default padding used by AlertDialog if insetPadding isn't set
          child: ConstrainedBox(
            constraints:  BoxConstraints.loose(Size(300, 300)),
            child: AlertDialog(
              insetPadding: EdgeInsets.zero,
              title: /* ... */,
              content: /* ...*/
            ),
          ),
        ),
      );
    },
  );

Upvotes: 0

Umar
Umar

Reputation: 418

wrap content with column and add widget like container set that width

showDialog(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        title: const Text("Bookmark"),
                        insetPadding: const EdgeInsets.all(0),
                        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
                        content: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Container(
                              color: Colors.red,
                              width: screen.width * 0.70,
                            )
                          ],
                        ),
                      );
                    });

Upvotes: 0

Lee Mordell
Lee Mordell

Reputation: 651

A Dialog's insetPadding property controls the padding around the dialog so you could set values to effectively reduce the height / width of the dialog, e.g.

    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            insetPadding: EdgeInsets.symmetric(
              horizontal: 50.0,
              vertical: 100.0,
            ),
            title: Text('...'),
            content: Text('...'),
          );
        });

Upvotes: 3

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277697

You can wrap it inside a SizedBox or ConstrainedBox

ConstrainedBox(
  constraints: BoxConstraints(maxHeight: 100.0),
  child: AlertDialog(
    ...
  ),
);

Alternatively, you can set shrinkWrap to true in your ListView so that it takes the least amount of vertical space necessary.

ListView(
  shrinkWrap: true,
  ...
)

Upvotes: 11

Andrey Gordeev
Andrey Gordeev

Reputation: 32559

Wrap your content with a Column and set mainAxisSize to MainAxisSize.min:

AlertDialog(
  content: Column(
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
      //your content
    ],
  ),

Upvotes: 47

Related Questions