본문 바로가기
Project/Google Solution Challenge 2024

[Flutter] Error: RenderFlex overflowed by Infinity pixels

by 빠니몽 2024. 1. 27.

01.27.2024

1. Error

════════════════ Exception caught by rendering library ══════════════════════════════
A RenderFlex overflowed by Infinity pixels on the bottom.
The relevant error-causing widget was
Column lib/pages/setting_page.dart:26
═══════════════════════════════════════════════════════════════════════

 

This error occurred when ListView was added and being rendered.

에러화면

2. Previous Code

// in settings_page.dart
import 'package:flutter/material.dart';
import 'package:strecording/widgets/profile_widget.dart';
import 'package:strecording/widgets/settings_widget.dart';

class SettingPage extends StatefulWidget {
  const SettingPage(
      {super.key,
      required this.email,
      required this.name,
      required this.profileImg});

  final String email;
  final String name;
  final String profileImg;

  @override
  State<SettingPage> createState() => _SettingPageState();
}

class _SettingPageState extends State<SettingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
		 // ...
          const SettingsWidget(),
         // ...
        ],
      ),
    ));
  }
}
// in settings_widget.dart
import 'package:flutter/material.dart';
import 'package:strecording/pages/login_page.dart';
import 'package:strecording/utilities/login_platform.dart';

class SettingsWidget extends StatefulWidget {
  const SettingsWidget({Key? key}) : super(key: key);

  @override
  State<SettingsWidget> createState() => _SettingsWidgetState();
}

class _SettingsWidgetState extends State<SettingsWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        shrinkWrap: true,
        children: <Widget>[
          ListTile(
            title: const Text('Diary notification'),
            trailing: Switch(
              value: true, // This should be a state variable
              onChanged: (bool value) {
                // Handle switch toggle
              },
            ),
          ),
          ListTile(
            title: const Text('Sign out'),
            onTap: () {
              AuthManager.signOut();
              Navigator.of(context).pushReplacement(
                  MaterialPageRoute(builder: (context) => const LoginPage()));
            },
          ),
          ListTile(
            title: const Text('Delete account'),
            onTap: () {
              // Handle account deletion
            },
          ),
        ],
      ),
    );
  }
}

3. Cause And Solution

3-1. Column()

In Flutter, Column() sizes itself to fit its children vertically. ListView() is scrollable, trying to take up as much as space it can. These qualities of them conflict when Column() has ListView() as a child.

3-2. Expanded()

To resolve this problem, use Expanded() and wrap the ListView or whatever component that occupies the remaining space of Column().

It tells Column() that the elements it holds should take up the rest of Column().

It essentially bounds the ListView to a finite size

4. The Final Code

import 'package:flutter/material.dart';
import 'package:strecording/widgets/profile_widget.dart';
import 'package:strecording/widgets/settings_widget.dart';

class SettingPage extends StatefulWidget {
  const SettingPage(
      {super.key,
      required this.email,
      required this.name,
      required this.profileImg});

  final String email;
  final String name;
  final String profileImg;

  @override
  State<SettingPage> createState() => _SettingPageState();
}

class _SettingPageState extends State<SettingPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
		// ...
          const Expanded(child: SettingsWidget()),
        // ...
        ],
      ),
    ));
  }
}