Center#
Center widget is one of the simplest yet most commonly used layout widgets. The Center widget aligns its child widget to the center of the available space β both vertically and horizontally.
Center(
key: β Identifies this widget uniquely in the widget tree.
widthFactor: β Multiplies the childβs width to determine the Centerβs width.
heightFactor: β Multiplies the childβs height to determine the Centerβs height.
child: β The widget you want to place in the center.
)
How to Call:
Center(
key: ValueKey('centerBox'),
widthFactor: 2.0,
heightFactor: 2.0,
child: Text('Kaftarya'),
)
β 1.key:#
β Fixed, minimal example
Goal: use MaterialApp.router() + RouterConfig + key: in Center.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// ------------------ App ------------------
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router, // β
use RouterConfig
);
}
}
// ------------------ Router Config ------------------
// Only routerDelegate β no routeInformationParser / provider
final RouterConfig<Object> _router = RouterConfig<Object>(
routerDelegate: _SimpleRouterDelegate(),
);
// ------------------ Router Delegate ------------------
class _SimpleRouterDelegate extends RouterDelegate<Object> with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
@override
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: const [
MaterialPage(child: HomePage()),
],
);
}
@override
Future<void> setNewRoutePath(Object configuration) async {
// Nothing to do for this simple example.
}
}
// ------------------ Home Page ------------------
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Center key: example')),
body: const Center(
key: ValueKey('main_center_widget'), // π key: parameter in Center
child: Text('Hello from Center widget'),
),
);
}
}
This is the part we are talking about:
body: const Center(
key: ValueKey('main_center_widget'),
child: Text('Hello from Center widget'),
),
1. What is key in Flutter? (simple meaning)
A key **is just an **ID card for a widget.
It tells Flutter:
βThis widget is THIS one. Donβt mix it with others.β
Flutter rebuilds the screen very fast. When it does that, it needs a way to recognize which widget is which. The key helps Flutter do that.
Without a key β Flutter guesses
With a key β Flutter knows exactly
2. What type of key did you use?
You used:
ValueKey('main_center_widget')
That means:
The value = βmain_center_widgetβ
Flutter uses that value to recognise the Center widget
As long as this value is the same, Flutter knows this is the same widget
Think of it like:
Real life |
Flutter |
|---|---|
Student ID |
Key |
Name on card |
Value in ValueKey |
Person |
Widget |
3. Why do you need a key here?
Right now, your app only has one page and one Center, so technically the app will still work without a key.
But you added it to learn and practice:
key: ValueKey('main_center_widget')
This will become very important when:
β You have multiple pages
β You have Lists (ListView / GridView)
β You move widgets around
β You update / replace widgets
β You use animations
In your restaurant app / Flutter project, you WILL need keys a lot.
4. What happens when the page rebuilds?
Your router uses:
MaterialPage(child: HomePage()),
When something changes, Flutter rebuilds HomePage.
Then it looks at widget tree and says:
βOkay, I see a Center widget. Does it look like an old one?β
It checks the key:
ValueKey('main_center_widget')
If the key is the same:
Flutter keeps the μν (state) if needed
Flutter doesnβt destroy and recreate unnecessarily
Keeps animations stable
If key changed or is missing:
Flutter may destroy the old widget
Create a new one
Lose state / animation progress
5. Test it yourself (important for learning)
Try changing the key to something else:
key: ValueKey('another_center'),
Run the app again.
π For you, visually it looks the same
π For Flutter, it becomes a different widget
That is the power of key.
Types of keys (very important to know)
In Flutter you mainly have 4 types:
Key |
Example |
Use |
|---|---|---|
ValueKey |
ValueKey(βhomeβ) |
Most common |
UniqueKey |
UniqueKey() |
Always new identity |
ObjectKey |
ObjectKey(user) |
Based on object |
GlobalKey |
GlobalKey() |
Access widget/state anywher |
You used: ValueKey β (best one for learning)
7. When you MUST use keys
You MUST use keys when:
Using ListView.builder
Using GridView
Reordering items
Animations with AnimatedSwitcher
Dynamic widgets from data
Your big enterprise app with 150+ tables UI
Example preview:
ListView(
children: [
Text('Apple', key: ValueKey('1')),
Text('Banana', key: ValueKey('2')),
Text('Orange', key: ValueKey('3')),
],
)
These keys protect items from being mixed up.
8. Final short summary
In your program:
key: ValueKey('main_center_widget')
Means:
β Give identity to Center
β Helps Flutter track widget
β Prevents wrong rebuild
β Used in routing, lists, animations
β Extremely important for big apps
β 2.widthFactor:#
Here is a clean, simple, WORKING Flutter program that uses
β MaterialApp.router()
β Center widget
β widthFactor: parameter in Center
β No errors, no deprecated code.
β Simple Flutter Program β widthFactor in Center (with MaterialApp.router)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// ------------------ App ------------------
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
// ------------------ Router Config ------------------
final RouterConfig<Object> _router = RouterConfig<Object>(
routerDelegate: _SimpleRouterDelegate(),
);
// ------------------ Router Delegate ------------------
class _SimpleRouterDelegate extends RouterDelegate<Object> with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
@override
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: const [
MaterialPage(child: HomePage()),
],
);
}
@override
Future<void> setNewRoutePath(Object configuration) async {}
}
// ------------------ Home Page ------------------
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Center widthFactor example')),
body: Center(
widthFactor: 2, // β
widthFactor parameter
child: Container(
color: Colors.blue,
width: 100,
height: 50,
child: const Center(
child: Text(
'Box',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
}
β What widthFactor is doing here
This line is the key:
Center(
widthFactor: 2,
Your child is:
Container(width: 100, height: 50)
So Flutter calculates the width of Center like this:
- Center width = childβs width Γ widthFactor
= 100 Γ 2
= 200px
Without widthFactor
The Center takes the full screen width
With widthFactor: 2
The Center becomes 200px wide
Still centered on the screen
Wraps tightly around the blue box
β Try this for learning
Change this line:
widthFactor: 2
Test values:
Value |
Result |
|---|---|
0.5 |
Smaller Center |
1 |
Same as child width |
2 |
Double width |
4 |
Very big Center |
null |
Full screen |
π Important note (best practice)
widthFactor only works when:
β Child has width
β If child has no width β nothing changes
Thatβs why I added:
width: 100,
One-line explanation
widthFactor = how wide the Center should be compared to its child
β 3.heightFactor:#
Here is a c**lean, simple, and error-free Flutter example** using:
β MaterialApp.router()
β Center
β heightFactor: parameter
β Simple Flutter Program β heightFactor in Center (MaterialApp.router)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// ------------------ App ------------------
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
// ------------------ Router Config ------------------
final RouterConfig<Object> _router = RouterConfig<Object>(
routerDelegate: _SimpleRouterDelegate(),
);
// ------------------ Router Delegate ------------------
class _SimpleRouterDelegate extends RouterDelegate<Object> with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
@override
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: const [
MaterialPage(child: HomePage()),
],
);
}
@override
Future<void> setNewRoutePath(Object configuration) async {}
}
// ------------------ Home Page ------------------
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Center heightFactor example')),
body: Center(
heightFactor: 3, // β
heightFactor parameter
child: Container(
color: Colors.green,
width: 100,
height: 40,
child: const Center(
child: Text(
'Box',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
}
β What heightFactor is doing here
Child height is:
height: 40,
You wrote:
heightFactor: 3,
So Flutter calculates the height of the Center like this:
Center height = child height Γ heightFactor
= 40 Γ 3
= 120px
Behavior:
With heightFactor |
What happens |
|---|---|
null |
Center takes full screen height |
1 |
Same height as child (40px) |
2 |
80px |
3 |
120px β |
5 |
200px |
It still stays perfectly centered vertically on the screen.
Very short explanation
heightFactor = how tall the Center becomes relative to its child
Try this (important for learning)
Change this line:
heightFactor: 3,
Test values:
0.5 (small)
1
2
4
null (default)
Feel the difference.
β 4.child:#
Here is a clean, simple, working Flutter example that uses
β MaterialApp.router()
β Center
β the child: parameter of Center
β Simple Flutter Program β child in Center (MaterialApp.router)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// ------------------ App ------------------
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
// ------------------ Router Config ------------------
final RouterConfig<Object> _router = RouterConfig<Object>(
routerDelegate: _SimpleRouterDelegate(),
);
// ------------------ Router Delegate ------------------
class _SimpleRouterDelegate extends RouterDelegate<Object> with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
@override
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: const [
MaterialPage(child: HomePage()),
],
);
}
@override
Future<void> setNewRoutePath(Object configuration) async {}
}
// ------------------ Home Page ------------------
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
appBar: AppBar(title: Text('Center child example')),
body: Center(
// β
child parameter of Center
child: Text(
'Hello! I am a child of Center',
style: TextStyle(fontSize: 20),
),
),
);
}
}
β What the child: parameter does
This line is the key:
child: Text('Hello! I am a child of Center'),
It means:
The child widget is the thing that goes inside the Center and gets positioned in the middle of the screen.
Center itself does not draw anything.
It only positions its child:
Horizontally in the center
Vertically in the center
You can put ANY widget as a child:
child: Text(...)
child: Icon(Icons.star)
child: Image.network(...)
child: Container(...)
child: Column(...)
π Very short explanation
Child = the widget you want to center
Without child, Center has nothing to show.