Overview

Center is a widget that centers its child within itself. It’s a convenience version of the Align widget with alignment: Alignment.center set, providing a simple way to center content.

Reference: https://api.flutter.dev/flutter/widgets/Center-class.html

When to Use

  • When centering content within a container
  • When displaying loading indicators in the center of the screen
  • When placing empty state messages in the center
  • When center-aligning dialog or modal content
  • When centering icons or logos

Basic Usage

// Simple center alignment
Center({
  child: Text('Centered text')
})

// Using with size factors
Center({
  widthFactor: 1.5,
  heightFactor: 2.0,
  child: Icon(Icons.star, { size: 48 })
})

// Full screen centering
Scaffold({
  body: Center({
    child: CircularProgressIndicator()
  })
})

Props

child (optional)

Type: Widget | undefined

The child widget to be centered.

widthFactor (optional)

Type: number | undefined

Sets this widget’s width as a multiple of the child widget’s width. If null, expands to available width.

Center({
  widthFactor: 2.0,  // 2 times the child's width
  child: Container({
    width: 100,
    height: 100,
    color: 'blue'
  })
})
// Center's width will be 200

heightFactor (optional)

Type: number | undefined

Sets this widget’s height as a multiple of the child widget’s height. If null, expands to available height.

Center({
  heightFactor: 1.5,  // 1.5 times the child's height
  child: Container({
    width: 100,
    height: 100,
    color: 'green'
  })
})
// Center's height will be 150

Center vs Align

Center is a special case of Align:

// These two are equivalent
Center({
  child: Text('Hello')
})

Align({
  alignment: Alignment.center,
  child: Text('Hello')
})

Layout Behavior

How Center widget determines its size:

  1. With tight constraints: Uses the constraint’s size
  2. With loose constraints and null factors: Expands as much as possible
  3. With infinite constraints and null factors: Uses the child’s size
  4. With specified factors: Child size × factor
// Various scenarios
Container({
  width: 200,
  height: 200,
  color: 'lightgray',
  child: Center({
    // Center expands to 200x200
    child: Container({
      width: 50,
      height: 50,
      color: 'blue'
    })
  })
})

Center({
  widthFactor: 2.0,
  heightFactor: 2.0,
  // Center is 100x100 (2x the child)
  child: Container({
    width: 50,
    height: 50,
    color: 'red'
  })
})

Practical Examples

Example 1: Loading Screen

const LoadingScreen = ({ message = 'Loading...' }) => {
  return Scaffold({
    body: Center({
      child: Column({
        mainAxisSize: MainAxisSize.min,
        children: [
          CircularProgressIndicator({
            size: 60,
            strokeWidth: 4
          }),
          SizedBox({ height: 24 }),
          Text(message, {
            style: TextStyle({
              fontSize: 18,
              color: '#666'
            })
          })
        ]
      })
    })
  });
};

Example 2: Empty State Display

const EmptyState = ({ icon, title, description, action }) => {
  return Center({
    child: Container({
      padding: EdgeInsets.all(32),
      child: Column({
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(icon, {
            size: 80,
            color: '#CCCCCC'
          }),
          SizedBox({ height: 24 }),
          Text(title, {
            style: TextStyle({
              fontSize: 24,
              fontWeight: 'bold',
              color: '#333'
            }),
            textAlign: TextAlign.center
          }),
          SizedBox({ height: 12 }),
          Text(description, {
            style: TextStyle({
              fontSize: 16,
              color: '#666'
            }),
            textAlign: TextAlign.center,
            maxLines: 3
          }),
          if (action) ...[
            SizedBox({ height: 32 }),
            action
          ]
        ]
      })
    })
  });
};

Example 3: Splash Screen

const SplashScreen = ({ logoUrl, appName }) => {
  return Scaffold({
    backgroundColor: '#2196F3',
    body: Center({
      child: Column({
        mainAxisSize: MainAxisSize.min,
        children: [
          Container({
            width: 120,
            height: 120,
            decoration: BoxDecoration({
              color: 'white',
              shape: BoxShape.circle,
              boxShadow: [
                BoxShadow({
                  color: 'rgba(0,0,0,0.2)',
                  blurRadius: 20,
                  offset: { x: 0, y: 10 }
                })
              ]
            }),
            child: Center({
              child: Image({
                src: logoUrl,
                width: 80,
                height: 80
              })
            })
          }),
          SizedBox({ height: 32 }),
          Text(appName, {
            style: TextStyle({
              fontSize: 28,
              fontWeight: 'bold',
              color: 'white',
              letterSpacing: 2
            })
          }),
          SizedBox({ height: 48 }),
          CircularProgressIndicator({
            valueColor: AlwaysStoppedAnimation('white')
          })
        ]
      })
    })
  });
};

Example 4: Error Message

const ErrorMessage = ({ error, onRetry }) => {
  return Container({
    padding: EdgeInsets.all(16),
    child: Center({
      widthFactor: 1.0,
      child: Container({
        padding: EdgeInsets.all(24),
        decoration: BoxDecoration({
          color: '#FFEBEE',
          borderRadius: BorderRadius.circular(12),
          border: Border.all({
            color: '#FFCDD2',
            width: 1
          })
        }),
        child: Column({
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.error_outline, {
              size: 48,
              color: '#F44336'
            }),
            SizedBox({ height: 16 }),
            Text('An error occurred', {
              style: TextStyle({
                fontSize: 18,
                fontWeight: 'bold',
                color: '#D32F2F'
              })
            }),
            SizedBox({ height: 8 }),
            Text(error.message, {
              style: TextStyle({
                fontSize: 14,
                color: '#D32F2F'
              }),
              textAlign: TextAlign.center
            }),
            if (onRetry) ...[
              SizedBox({ height: 20 }),
              ElevatedButton({
                onPressed: onRetry,
                child: Text('Try Again'),
                style: ButtonStyle({
                  backgroundColor: '#F44336'
                })
              })
            ]
          ]
        })
      })
    })
  });
};

Example 5: Dialog Content

const DialogContent = ({ icon, title, message, actions }) => {
  return Container({
    width: 300,
    padding: EdgeInsets.all(24),
    child: Column({
      mainAxisSize: MainAxisSize.min,
      children: [
        Center({
          child: Container({
            width: 64,
            height: 64,
            decoration: BoxDecoration({
              color: '#E3F2FD',
              shape: BoxShape.circle
            }),
            child: Center({
              child: Icon(icon, {
                size: 32,
                color: '#2196F3'
              })
            })
          })
        }),
        SizedBox({ height: 20 }),
        Center({
          child: Text(title, {
            style: TextStyle({
              fontSize: 20,
              fontWeight: 'bold'
            })
          })
        }),
        SizedBox({ height: 12 }),
        Center({
          child: Text(message, {
            style: TextStyle({
              fontSize: 16,
              color: '#666'
            }),
            textAlign: TextAlign.center
          })
        }),
        SizedBox({ height: 24 }),
        Center({
          child: Row({
            mainAxisSize: MainAxisSize.min,
            children: actions
          })
        })
      ]
    })
  });
};

Important Notes

  • Center expands as much as possible by default, so be careful in Stack or infinite size containers
  • widthFactor and heightFactor must be greater than 0
  • Nesting multiple Centers is generally unnecessary
  • For complex alignment needs, use Align widget directly
  • When there’s no child and factor is null, size may become 0
  • Align: Parent widget providing more alignment options
  • Container: Can center align with alignment property
  • Positioned: Position within Stack
  • Padding: When centering with margins is needed
  • Column/Row: Align with mainAxisAlignment and crossAxisAlignment