# flutter_widgets **Repository Path**: liggplus/flutter_widgets ## Basic Information - **Project Name**: flutter_widgets - **Description**: flutter基础 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-01 - **Last Updated**: 2025-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 📚 Flutter 常用基础组件全览(含属性说明与 Demo) > 目标:按类别梳理 Flutter 常用基础组件,补齐**作用说明**、**常用属性(数据)**与**属性作用**,并提供**可复用 Demo**。 > 说明:示例以 `MaterialApp`/`Scaffold` 场景为主,属性表只列**高频**与**易混**字段。 --- ## 目录 - [布局(Layout)](#布局layout) - [滚动与列表(Scroll & Lists)](#滚动与列表scroll--lists) - [显示与装饰(Display & Decoration)](#显示与装饰display--decoration) - [输入与交互(Input & Interaction)](#输入与交互input--interaction) - [导航与骨架(Navigation & Structure)](#导航与骨架navigation--structure) - [反馈与状态(Feedback & Status)](#反馈与状态feedback--status) - [适配与主题(Adaptation & Theming)](#适配与主题adaptation--theming) --- ## 布局(Layout) ### 1. `Container` **作用**:单节点万能容器,支持**约束**、**对齐**、**装饰**、**外/内边距**。 | 属性 | 类型 | 作用 | 示例 | |---|---|---|---| | `child` | `Widget?` | 子组件 | `Text('Hi')` | | `padding`/`margin` | `EdgeInsetsGeometry?` | 内/外边距 | `EdgeInsets.all(12)` | | `alignment` | `AlignmentGeometry?` | 子组件对齐 | `Alignment.center` | | `decoration` | `Decoration?` | 背景、圆角、边框 | `BoxDecoration(color: Colors.blue, borderRadius: BorderRadius.circular(12))` | | `constraints` | `BoxConstraints?` | 尺寸约束 | `BoxConstraints.tight(Size(100,40))` | | `clipBehavior` | `Clip` | 是否裁剪 | `Clip.antiAlias` | **Demo** ```dart Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), alignment: Alignment.centerLeft, constraints: const BoxConstraints(minHeight: 48), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.blue.shade200), ), child: const Text('Container · 布局/装饰/约束'), ) ``` --- ### 2. `Row` / `Column` **作用**:线性排列子组件(水平/垂直)。 | 属性 | 类型 | 作用 | 常用值 | |---|---|---|---| | `children` | `List` | 子组件列表 | `[...]` | | `mainAxisAlignment` | `MainAxisAlignment` | 主轴分布 | `start/center/spaceBetween` | | `crossAxisAlignment` | `CrossAxisAlignment` | 交叉轴对齐 | `start/center/stretch` | | `mainAxisSize` | `MainAxisSize` | 主轴尺寸 | `min/max` | | `textDirection` | `TextDirection?` | 文字/布局方向 | `ltr/rtl` | **Demo** ```dart Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: const [ FlutterLogo(size: 32), Text('Row 中间文本'), Icon(Icons.settings), ], ); ``` --- ### 3. `Expanded` / `Flexible` / `Spacer` **作用**:在 `Row`/`Column` 中控制**弹性占位**。`Expanded` 等价于 `Flexible(fit: FlexFit.tight)`。 | 组件 | 关键属性 | 说明 | |---|---|---| | `Expanded` | `flex` | 按权重分配剩余空间(强制充满) | | `Flexible` | `flex`, `fit` | `loose` 不强制充满 | | `Spacer` | `flex` | 空白占位,内部就是 `Expanded(SizedBox.shrink())` | **Demo** ```dart Row( children: const [ Expanded(flex: 2, child: ColoredBox(color: Colors.teal, child: SizedBox(height: 40))), Spacer(), // 等价于 Expanded(flex:1) Expanded(flex: 1, child: ColoredBox(color: Colors.orange, child: SizedBox(height: 40))), ], ); ``` --- ### 4. `Padding` / `Align` / `Center` / `SizedBox` **作用**:微布局常用小组件。 | 组件 | 关键属性 | 作用 | |---|---|---| | `Padding` | `padding` | 包裹内边距 | | `Align` | `alignment`, `widthFactor/heightFactor` | 对齐与拉伸比例 | | `Center` | 无 | `Align(alignment: center)` 的便捷版 | | `SizedBox` | `width/height`, `child` | 固定/最小尺寸占位 | **Demo** ```dart const SizedBox( width: 200, child: Padding( padding: EdgeInsets.all(12), child: Align(alignment: Alignment.centerRight, child: Text('右对齐')), ), ); ``` --- ### 5. `Stack` / `Positioned` **作用**:层叠布局;`Positioned` 用于绝对定位。 | 属性 | 类型 | 作用 | |---|---|---| | `alignment` | `AlignmentGeometry` | 未定位子元素对齐 | | `fit` | `StackFit` | 未定位子元素填充方式 | | `clipBehavior` | `Clip` | 裁剪 | **Demo** ```dart Stack( clipBehavior: Clip.none, children: [ Container(height: 120, color: Colors.indigo.shade100), const Positioned(right: 12, bottom: -10, child: Chip(label: Text('绝对定位'))), ], ); ``` --- ### 6. 其他常用布局 - `Wrap`:自动换行/流式布局(`spacing`、`runSpacing`、`alignment`)。 - `AspectRatio`:以固定宽高比布局。 - `FittedBox`:等比缩放其子组件以适应父布局。 - `FractionallySizedBox`:以父尺寸百分比布局。 - `LayoutBuilder`:获取父约束,做自适应分支。 **Demo(Wrap)** ```dart Wrap( spacing: 8, runSpacing: 8, children: List.generate(8, (i) => Chip(label: Text('Tag $i'))), ); ``` --- ## 滚动与列表(Scroll & Lists) ### 1. `ListView` **作用**:可滚动列表;优先使用 `builder`/`separated` 构造节省内存。 | 构造器 | 说明 | |---|---| | `ListView(children: ...)` | 小量静态项 | | `ListView.builder(itemBuilder: ...)` | 大量/懒加载 | | `ListView.separated` | 带分隔线 | | 常用属性 | `scrollDirection`、`controller`、`physics`、`padding` | **Demo(builder)** ```dart ListView.builder( itemCount: 50, itemBuilder: (context, i) => ListTile( leading: CircleAvatar(child: Text('${i+1}')), title: Text('Item $i'), subtitle: const Text('说明文字'), ), ); ``` --- ### 2. `GridView` **作用**:网格列表。 | 构造器 | 说明 | |---|---| | `GridView.count(crossAxisCount: n)` | 固定列数 | | `GridView.extent(maxCrossAxisExtent: w)` | 最大交叉轴宽度 | | `GridView.builder(gridDelegate: ...)` | 高性能/懒加载 | **关键属性** - `gridDelegate`: `SliverGridDelegateWithFixedCrossAxisCount/WithMaxCrossAxisExtent` - `crossAxisSpacing`、`mainAxisSpacing`、`childAspectRatio`。 **Demo** ```dart GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 8, crossAxisSpacing: 8, childAspectRatio: .8), itemCount: 12, itemBuilder: (_, i) => Card(child: Center(child: Text('G$i'))), ); ``` --- ### 3. `SingleChildScrollView` **作用**:单子节点滚动容器(不复用,不宜用于长列表)。 | 属性 | 作用 | |---|---| | `scrollDirection` | 滚动方向 | | `physics` | 滚动物理效果 | | `padding` | 内边距 | **Demo** ```dart SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column(children: List.generate(30, (i) => Text('Line $i'))), ); ``` --- ### 4. `CustomScrollView` + Slivers **作用**:组合 `SliverAppBar`、`SliverList`/`Grid` 等实现高阶滚动效果(吸顶、折叠)。 **Demo(折叠头 + 列表)** ```dart CustomScrollView( slivers: [ SliverAppBar( pinned: true, expandedHeight: 160, flexibleSpace: const FlexibleSpaceBar(title: Text('Sliver AppBar')), ), SliverList( delegate: SliverChildBuilderDelegate( (context, i) => ListTile(title: Text('Row $i')), childCount: 30, ), ), ], ); ``` --- ### 5. `PageView` **作用**:页面级横向/纵向翻页。 | 属性 | 作用 | |---|---| | `controller` | 控制器,支持跳页、监听 | | `onPageChanged` | 页变更回调 | | `pageSnapping` | 是否自动捕捉 | **Demo** ```dart PageView( onPageChanged: print, children: const [Center(child: Text('A')), Center(child: Text('B')), Center(child: Text('C'))], ); ``` --- ## 显示与装饰(Display & Decoration) ### 1. `Text` / `RichText` **作用**:文本显示;`RichText` 支持富文本(不同样式片段)。 | `Text` 常用属性 | 作用 | |---|---| | `style` | 字体、颜色、行高等 | | `textAlign` | 对齐 | | `maxLines`/`overflow` | 截断、省略号 | | `softWrap` | 自动换行 | **Demo(溢出省略 + 富文本)** ```dart const Text( '这是一段很长很长的文本……', maxLines: 1, overflow: TextOverflow.ellipsis, ); const RichText( text: TextSpan( text: 'Hello ', style: TextStyle(color: Colors.black), children: [TextSpan(text: 'Flutter', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.blue))], ), ); ``` --- ### 2. `Image` / `FadeInImage` / `CircleAvatar` **作用**:图片展示与占位渐显、圆形头像。 | 常用属性 | 作用 | |---|---| | `fit` | 填充/裁剪 | | `width/height` | 尺寸 | | `loadingBuilder/errorBuilder` | 进度/错误占位 | **Demo** ```dart FadeInImage.assetNetwork( placeholder: 'assets/placeholder.png', image: 'https://picsum.photos/400', width: 200, height: 120, fit: BoxFit.cover, ); ``` --- ### 3. `Icon` / `IconTheme` **作用**:图标与全局图标样式。 **Demo** ```dart IconTheme( data: const IconThemeData(size: 28), child: Row(children: const [Icon(Icons.home), Icon(Icons.star), Icon(Icons.settings)]), ); ``` --- ### 4. `Card` / `ListTile` / `Divider` / `Chip` / `Tooltip` **作用**:信息卡片、条目、分割线、标签、悬浮提示。 **Demo(卡片 + 列表项)** ```dart Card( margin: const EdgeInsets.all(12), elevation: 2, child: const ListTile( leading: Icon(Icons.person), title: Text('用户名'), subtitle: Text('副标题/说明'), trailing: Icon(Icons.chevron_right), ), ); ``` --- ## 输入与交互(Input & Interaction) ### 1. 按钮族(Material 3) - `ElevatedButton`:高强调主按钮 - `FilledButton`:实心按钮(M3,略低强调) - `OutlinedButton`:描边按钮 - `TextButton`:文字按钮 - `IconButton` / `FloatingActionButton` **共性属性**:`onPressed`、`onLongPress`、`style`、`child/icon`。 **Demo** ```dart Row( children: [ ElevatedButton(onPressed: () {}, child: const Text('Primary')), const SizedBox(width: 8), OutlinedButton(onPressed: () {}, child: const Text('Outline')), const SizedBox(width: 8), TextButton(onPressed: () {}, child: const Text('Text')), ], ); ``` --- ### 2. `GestureDetector` / `InkWell` **作用**:手势检测;`InkWell` 带水波纹(需 `Material` 祖先)。 | 手势 | 回调 | |---|---| | 点击 | `onTap`/`onDoubleTap` | | 长按 | `onLongPress` | | 拖拽 | `onPanStart/Update/End` | **Demo(InkWell)** ```dart Material( color: Colors.transparent, child: InkWell( onTap: () {}, borderRadius: BorderRadius.circular(8), child: const Padding(padding: EdgeInsets.all(12), child: Text('可点的文字')), ), ); ``` --- ### 3. 表单:`Form` + `TextFormField` **作用**:带校验的输入集合。 | 属性 | 作用 | |---|---| | `validator` | 校验器,返回错误文本 | | `autovalidateMode` | 自动校验时机 | | `onSaved` | 提交时保存 | **Demo** ```dart final _formKey = GlobalKey(); Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextFormField( decoration: const InputDecoration(labelText: '邮箱'), validator: (v) => (v == null || !v.contains('@')) ? '邮箱格式错误' : null, ), const SizedBox(height: 12), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // 通过校验 } }, child: const Text('提交'), ), ], ), ); ``` --- ### 4. 选择类:`Checkbox` / `Radio` / `Switch` / `Slider` / `DropdownButton` **关键属性**:`value`、`onChanged`、`activeColor`/`thumbColor`、`items`(下拉)。 **Demo(DropdownButton)** ```dart String? selected = 'A'; DropdownButton( value: selected, items: const [ DropdownMenuItem(value: 'A', child: Text('选项 A')), DropdownMenuItem(value: 'B', child: Text('选项 B')), ], onChanged: (v) => selected = v, ); ``` --- ### 5. 选择器弹窗(函数式) - `showDatePicker` / `showTimePicker`:日期/时间选择 - `showSearch`:内置搜索页(需 `SearchDelegate`) **Demo(日期选择)** ```dart final date = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime(2100), ); ``` --- ## 导航与骨架(Navigation & Structure) ### 1. `MaterialApp` / `Theme` / `Scaffold` **作用**:应用根、主题与页面骨架。 | 组件 | 关键点 | |---|---| | `MaterialApp` | `routes`、`onGenerateRoute`、`theme`/`darkTheme`、`home` | | `Theme` | `ThemeData`/`ColorScheme` 覆盖局部主题 | | `Scaffold` | `appBar`、`body`、`floatingActionButton`、`drawer`、`bottomNavigationBar` | **Demo(骨架)** ```dart MaterialApp( theme: ThemeData(colorSchemeSeed: Colors.indigo, useMaterial3: true), home: Scaffold( appBar: AppBar(title: const Text('首页')), body: const Center(child: Text('Hello')), floatingActionButton: FloatingActionButton(onPressed: () {}), ), ); ``` --- ### 2. `AppBar` / `TabBar` + `TabBarView` **作用**:顶部栏与标签页。 | `AppBar` 属性 | 作用 | |---|---| | `title`/`centerTitle` | 标题/居中 | | `actions` | 右侧操作 | | `bottom` | 放 `TabBar`/自定义栏 | **Demo(Tab)** ```dart DefaultTabController( length: 3, child: Scaffold( appBar: AppBar( title: const Text('标签页'), bottom: const TabBar(tabs: [Tab(text:'A'), Tab(text:'B'), Tab(text:'C')]), ), body: const TabBarView(children: [ Center(child: Text('A')), Center(child: Text('B')), Center(child: Text('C')), ]), ), ); ``` --- ### 3. 底部与侧边:`NavigationBar`/`BottomNavigationBar`/`NavigationRail`/`Drawer` **作用**:多页导航(移动/平板/桌面)。 **Demo(BottomNavigationBar)** ```dart int current = 0; Scaffold( bottomNavigationBar: BottomNavigationBar( currentIndex: current, onTap: (i) => current = i, items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.search), label: '发现'), BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'), ], ), body: const Center(child: Text('切换 body 实现多页')), ); ``` --- ### 4. 路由:`Navigator` / `Hero` **作用**:页面跳转与共享元素动画。 **Demo(基本路由)** ```dart Navigator.of(context).push(MaterialPageRoute(builder: (_) => const DetailPage())); ``` **Demo(Hero)** ```dart Hero(tag: 'avatar', child: CircleAvatar(backgroundImage: NetworkImage(url))); ``` --- ## 反馈与状态(Feedback & Status) ### 1. `SnackBar` / `MaterialBanner` **作用**:临时提示(底部/顶部区域)。 | 属性 | 作用 | |---|---| | `content` | 主内容 | | `action` | 行动按钮(SnackBarAction) | | `behavior` | 浮动/固定 | **Demo(SnackBar)** ```dart ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('已保存'), action: SnackBarAction(label: '撤销', onPressed: () {}), ), ); ``` --- ### 2. `AlertDialog` / `SimpleDialog` / `BottomSheet` **作用**:确认/选择/底部行为面板。 **Demo(AlertDialog)** ```dart showDialog( context: context, builder: (_) => AlertDialog( title: const Text('提示'), content: const Text('确定要删除吗?'), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')), FilledButton(onPressed: () {}, child: const Text('删除')), ], ), ); ``` **Demo(Modal BottomSheet)** ```dart showModalBottomSheet( context: context, shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))), builder: (_) => ListView( shrinkWrap: true, children: const [ListTile(title: Text('操作 1')), ListTile(title: Text('操作 2'))], ), ); ``` --- ### 3. 进度:`CircularProgressIndicator` / `LinearProgressIndicator` | 属性 | 作用 | |---|---| | `value` | 非空即为**确定进度**(0~1) | | `semanticsLabel` | 无障碍描述 | **Demo** ```dart const LinearProgressIndicator(value: 0.6); ``` --- ## 适配与主题(Adaptation & Theming) ### 1. `SafeArea` / `MediaQuery` / `OrientationBuilder` **作用**:避让系统区域、获取屏幕信息、适配横竖屏。 **Demo** ```dart SafeArea( child: OrientationBuilder( builder: (_, ori) => Text('方向: $ori · 宽:${MediaQuery.of(_).size.width.toStringAsFixed(0)}'), ), ); ``` --- ### 2. `Theme` / `ThemeData` / `ColorScheme` **作用**:统一主题与色板;M3 推荐以 `ColorScheme` 驱动。 **Demo(局部覆盖)** ```dart Theme( data: Theme.of(context).copyWith( textTheme: Theme.of(context).textTheme.apply(bodyColor: Colors.deepPurple), ), child: const Text('局部主题'), ); ``` --- ## 附:推荐组合模板 ### 表单页模板 ```dart class DemoFormPage extends StatefulWidget { const DemoFormPage({super.key}); @override State createState() => _DemoFormPageState(); } class _DemoFormPageState extends State { final _formKey = GlobalKey(); bool agree = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('注册')), body: Padding( padding: const EdgeInsets.all(16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextFormField( decoration: const InputDecoration(labelText: '邮箱'), validator: (v) => (v == null || !v.contains('@')) ? '请输入有效邮箱' : null, ), const SizedBox(height: 12), TextFormField( decoration: const InputDecoration(labelText: '密码'), obscureText: true, validator: (v) => (v == null || v.length < 6) ? '至少 6 位' : null, ), const SizedBox(height: 12), Row( children: [ Checkbox(value: agree, onChanged: (v) => setState(() => agree = v ?? false)), const Expanded(child: Text('我已阅读并同意条款')), ], ), const SizedBox(height: 12), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate() && agree) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('提交成功'))); } }, child: const Text('提交'), ), ], ), ), ), ); } } ``` ### 列表 + 详情(路由)模板 ```dart class ListPage extends StatelessWidget { const ListPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('文章列表')), body: ListView.separated( itemBuilder: (_, i) => ListTile( title: Text('标题 $i'), subtitle: const Text('摘要内容'), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => DetailPage(index: i))), ), separatorBuilder: (_, __) => const Divider(height: 0), itemCount: 30, ), ); } } class DetailPage extends StatelessWidget { final int index; const DetailPage({super.key, required this.index}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('详情 $index')), body: Padding( padding: const EdgeInsets.all(16), child: Text('这里是第 $index 篇文章的内容……'), ), ); } } ``` --- ## 小结与使用建议 - 列表优先 `builder` 构造;长列表使用 `Sliver` 组合做吸顶/折叠。 - 弹性布局场景优先 `Expanded/Flexible/Spacer`,避免硬编码宽高。 - 表单请用 `Form + TextFormField + validator`,统一校验与提交流程。 - 主题统一由 `ThemeData/ColorScheme` 驱动,局部主题用 `Theme` 包裹覆盖。 > **高级组件**: [Flutter Widgets](https://flutter.dev)