已发布·持续改进
Flutter 指南 · 3/6
本章目前仅提供英文版。
The starting point for understanding Flutter is that everything is a widget. Text, buttons, padding, alignment, whole screens and the app itself are all widgets, and you build UIs by composing small widgets into larger ones. This chapter covers the two kinds of widgets, the build method, layout, the design libraries and navigation.
A widget is a lightweight, immutable description of how part of the UI should look. When state changes, Flutter builds a new widget tree, compares it with the previous one and repaints only what actually changed, so creating widgets often is cheap.
Flutter does not use the platform's native UI controls. Its own rendering engine draws every pixel, which keeps the UI consistent across platforms and makes custom designs and animations straightforward.
A StatelessWidget renders purely from the values it receives in its constructor; it has no data of its own that changes.
class Greeting extends StatelessWidget {
const Greeting({super.key, required this.name});
final String name;
@override
Widget build(BuildContext context) {
return Text('Hello, $name', style: Theme.of(context).textTheme.headlineSmall);
}
}A StatefulWidget holds state that changes over time. It is split into the widget class and a State class, and every state change must happen inside setState so Flutter knows to rebuild.
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Pressed $_count times'),
FilledButton(
onPressed: () => setState(() => _count++),
child: const Text('Add'),
),
],
);
}
}The State object survives when its widget is rebuilt. Do one-time setup in initState and release controllers and subscriptions in dispose.
build returns the widgets that describe the UI, and it may run many times as state changes. Keep it cheap: no network calls or heavy computation, just turn data you already have into widgets.
BuildContext is the widget's location in the tree. Use it to look up information from ancestors, as in Theme.of(context), MediaQuery.sizeOf(context) or Navigator.of(context). Marking widgets that never change as const lets Flutter skip rebuilding them.
Layout in Flutter is done with widgets too:
| Widget | Purpose |
|---|---|
Row, Column | Lay out children horizontally or vertically |
Expanded, Flexible | Share remaining space inside a Row or Column |
Stack, Positioned | Overlap widgets |
Padding, SizedBox, Center, Align | Spacing, size and alignment |
Container | Padding, background, border and size in one |
ListView, GridView | Scrollable lists and grids |
The core rule is: constraints go down, sizes go up, and the parent sets the position. A parent tells its child the minimum and maximum size allowed, the child picks a size within that range, and the parent decides where to place it.
Widget buildProfile() {
return Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
const CircleAvatar(radius: 24, child: Icon(Icons.person)),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Jane Doe', style: TextStyle(fontWeight: FontWeight.bold)),
Text('Flutter developer'),
],
),
),
IconButton(onPressed: () {}, icon: const Icon(Icons.more_vert)),
],
),
);
}For long lists, use ListView.builder so only the visible items are built.
Flutter ships two design libraries. Material follows Google's Material Design (Material 3 by default) with MaterialApp, Scaffold, AppBar, FilledButton and more. Cupertino provides iOS-style widgets such as CupertinoApp, CupertinoButton and CupertinoNavigationBar.
MaterialApp(
title: 'Todos',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo, brightness: Brightness.dark),
),
home: Scaffold(
appBar: AppBar(title: const Text('Todos')),
body: const Center(child: Text('Nothing to do yet')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
),
);You can mix both libraries in one app, and adaptive constructors such as Switch.adaptive change their look to match the platform.
Basic navigation is handled by Navigator, a stack of routes: push adds a screen on top and pop returns to the previous one.
// Go to the detail screen
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const DetailScreen()),
);
// Go back
Navigator.of(context).pop();For URL-based routing, deep links and browser address bar support, many apps use the go_router package maintained by the Flutter team.
setState when it does.build runs often, so keep it light and mark unchanging widgets const.
0 条评论
登录 · 登录后即可发表评论。
来发表第一条评论吧。