I'm trying to display an AlertDialog widget with 2 RadioListTile inside but I get a rendering exception.

Here is the code for the AlertDialog:

enum _Theme { light, dark }

class ChangeThemeDialog extends StatefulWidget {
  @override
  _ChangeThemeDialogState createState() => _ChangeThemeDialogState();
}

class _ChangeThemeDialogState extends State<ChangeThemeDialog> {
  _Theme _theme = _Theme.light;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(AppLocalizations.of(context).changeThemeDialogTitle),
      content: Text(AppLocalizations.of(context).changeThemeDialogContent),
      actions: <Widget>[
        RadioListTile<_Theme>(
          title: const Text('Light'),
          value: _Theme.light,
          groupValue: _theme,
          onChanged: (_Theme value) {
            setState(() {
              _theme = value;
            });
          },
        ),
        RadioListTile<_Theme>(
          title: const Text('Dark'),
          value: _Theme.dark,
          groupValue: _theme,
          onChanged: (_Theme value) {
            setState(() {
              _theme = value;
            });
          },
        ),
      ],
    );
  }
}

Here is the exception raised:


════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite width.

These invalid constraints were provided to RenderParagraph's layout() function by the following function, which probably computed the invalid constraints in question:
  _RenderListTile._layoutBox (package:flutter/src/material/list_tile.dart:1318:9)
The offending constraints were: BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
The relevant error-causing widget was
    RadioListTile<_Theme> 
lib\…\widgets\change_theme_dialog.dart:21
When the exception was thrown, this was the stack
#0      BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError 
package:flutter/…/rendering/box.dart:517
#1      BoxConstraints.debugAssertIsValid.<anonymous closure> 
package:flutter/…/rendering/box.dart:559
#2      BoxConstraints.debugAssertIsValid 
package:flutter/…/rendering/box.dart:565
#3      RenderObject.layout 
package:flutter/…/rendering/object.dart:1670
#4      _RenderListTile._layoutBox 
package:flutter/…/material/list_tile.dart:1318
...
The following RenderObject was being processed when the exception was fired: _RenderListTile#940e2 relayoutBoundary=up18 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
RenderObject: _RenderListTile#940e2 relayoutBoundary=up18 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    parentData: offset=Offset(0.0, 0.0) (can use size)
    constraints: BoxConstraints(unconstrained)
    size: MISSING
    leading: RenderMouseRegion#0f7c8 relayoutBoundary=up19 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        parentData: offset=Offset(0.0, 0.0) (can use size)
        constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=56.0)
        size: Size(40.0, 40.0)
        listeners: enter, exit
        child: RenderSemanticsAnnotations#f6e87 relayoutBoundary=up20 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
            parentData: <none> (can use size)
            constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=56.0)
            size: Size(40.0, 40.0)
            child: _RenderRadio#76d2d relayoutBoundary=up21 NEEDS-PAINT
                parentData: <none> (can use size)
                constraints: BoxConstraints(0.0<=w<=Infinity, 0.0<=h<=56.0)
                size: Size(40.0, 40.0)
                additionalConstraints: BoxConstraints(w=40.0, h=40.0)
                value: checked
    title: RenderParagraph#88552 NEEDS-LAYOUT NEEDS-PAINT
        parentData: offset=Offset(0.0, 0.0)
        constraints: MISSING
        size: MISSING
        textAlign: start
        textDirection: ltr
        softWrap: wrapping at box width
        overflow: clip
        locale: it_IT
        maxLines: unlimited
        text: TextSpan
            debugLabel: ((englishLike subhead 2014).merge(((blackMountainView subtitle1).apply).merge(unknown))).copyWith
            inherit: false
            color: Color(0xdd000000)
            family: Prompt
            size: 16.0
            weight: 400
            letterSpacing: 0.1
            baseline: alphabetic
            decoration: TextDecoration.none
            "Light"

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: _RenderListTile#940e2 relayoutBoundary=up18 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
    RadioListTile<_Theme> 
lib\…\widgets\change_theme_dialog.dart:21
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderPadding#399f0 relayoutBoundary=up17 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
    RadioListTile<_Theme> 
lib\…\widgets\change_theme_dialog.dart:21
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderSemanticsAnnotations#b25db relayoutBoundary=up16 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
    RadioListTile<_Theme> 
lib\…\widgets\change_theme_dialog.dart:21
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════


Solution 1: Sebastian

Don't use an ActionDialog, use just a Dialog with a Column inside.

Like this

Widget build(BuildContext context) {
    return Dialog(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          RadioListTile<String>(
            title: const Text('Light'),
            value: 'light',
            // groupValue: _theme,
            onChanged: null,
          ),
          RadioListTile<String>(
            title: const Text('Dark'),
            value: 'dark',
            // groupValue: _theme,
            onChanged: null,
          ),
        ],
      ),
    );
  }


Solution 2: chunhunghan

You can copy paste run full code below
You can wrap RadioListTile with Container and provide width
code snippet

Container(
          width: 150,
          child: RadioListTile<_Theme>(

working demo

enter image description here

full code

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

enum _Theme { light, dark }

class ChangeThemeDialog extends StatefulWidget {
  @override
  _ChangeThemeDialogState createState() => _ChangeThemeDialogState();
}

class _ChangeThemeDialogState extends State<ChangeThemeDialog> {
  _Theme _theme = _Theme.light;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text("title"),
      content: Text("content"),
      actions: <Widget>[
        Container(
          width: 150,
          child: RadioListTile<_Theme>(
            title: const Text('Light'),
            value: _Theme.light,
            groupValue: _theme,
            onChanged: (_Theme value) {
              setState(() {
                _theme = value;
              });
            },
          ),
        ),
        Container(
          width: 150,
          child: RadioListTile<_Theme>(
            title: const Text('Dark'),
            value: _Theme.dark,
            groupValue: _theme,
            onChanged: (_Theme value) {
              setState(() {
                _theme = value;
              });
            },
          ),
        )
      ],
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ChangeThemeDialog(),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}