| 组件 | 说明 | 示例 |
|---|---|---|
| Text | 显示文本 | Text(‘Hello Flutter’, style: TextStyle(fontSize: 20)) |
| Image | 显示图片 | Image.network(‘https://example.com/image.jpg’) |
| Icon | 显示图标 | Icon(Icons.home, size: 30, color: Colors.blue) |
| RaisedButton / ElevatedButton | 按钮 | ElevatedButton(onPressed: () {}, child: Text(‘Click’)) |
| TextField | 输入框 | TextField(decoration: InputDecoration(labelText: ‘Name’)) |
|
1 2 3 4 5 6 7 |
Text( 'Flutter 组件配置详解', style: TextStyle(fontSize: 20, color: Colors.black, fontWeight: FontWeight.bold), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| data | String | 显示的文本内容 |
| style | TextStyle | 字体大小、颜色、行高等 |
| textAlign | TextAlign | 文本对齐(left、right、center、justify) |
| maxLines | int | 最大显示行数 |
| overflow | TextOverflow | 溢出处理:ellipsis(省略号)等 |
|
1 2 3 4 5 6 7 |
Image.network( 'https://example.com/image.jpg', width: 200, height: 100, fit: BoxFit.cover, alignment: Alignment.center, ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| image | ImageProvider | 图片数据,如 AssetImage, NetworkImage |
| width / height | double | 宽/高 |
| fit | BoxFit | 缩放方式:fill、cover、contain、fitWidth、fitHeight |
| repeat | ImageRepeat | 是否重复显示图片 |
| alignment | Alignment | 对齐方式 |
|
1 2 3 4 5 |
Icon( Icons.home, size: 30, color: Colors.green, ) |
|
1 2 3 4 5 6 7 8 9 10 |
ElevatedButton( onPressed: () => print('Clicked'), child: Text('提交'), style: ElevatedButton.styleFrom( primary: Colors.blue, onPrimary: Colors.white, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| onPressed | Function() | 按钮点击事件 |
| child | Widget | 按钮内容 |
| style | ButtonStyle | 自定义样式:背景色、形状、边距 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
TextField( controller: _usernameController, obscureText: false, keyboardType: TextInputType.text, maxLength: 20, decoration: InputDecoration( labelText: '用户名', hintText: '请输入用户名', prefixIcon: Icon(Icons.person), border: OutlineInputBorder(), ), onChanged: (value) { print('输入内容:$value'); }, ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| controller | TextEditingController | 控制器(获取/设置输入值) |
| decoration | InputDecoration | 输入框装饰 |
| obscureText | bool | 是否隐藏内容(密码输入) |
| keyboardType | TextInputType | 键盘类型:text、number、email 等 |
| maxLength | int | 最大输入长度 |
| onChanged | (value) => void | 内容改变时的回调 |
| 组件 | 说明 | 示例 |
|---|---|---|
| Row / Column | 横/纵向布局 | Row(children: [Text(‘A’), Text(‘B’)]) |
| Container | 容器,可设大小、颜色、边距等 | Container(width: 100, height: 100, color: Colors.red) |
| Padding | 添加内边距 | Padding(padding: EdgeInsets.all(8), child: Text(‘Padded’)) |
| Expanded | 撑满剩余空间 | Expanded(child: Container(color: Colors.green)) |
| Stack | 叠层布局 | Stack(children: […]) |
| 组件 | 说明 | 示例代码 |
|---|---|---|
| Container | 常用容器组件,支持 padding、margin、decoration | Container(width: 100, margin: EdgeInsets.all(10)) |
| Padding | 仅设置内边距 | Padding(padding: EdgeInsets.all(10), child: ...) |
| Align / Center | 对齐子组件 | Center(child: Text("中间")) |
| Row / Column | 横向或纵向排列子组件 | Row(children: [Text("A"), Text("B")]) |
| Expanded | 填满剩余空间 | Expanded(child: Container(color: Colors.red)) |
| SizedBox | 固定宽高或空隙 | SizedBox(height: 20) |
| Stack | 组件层叠 | Stack(children: [Container(), Positioned(...)]) |
| Wrap | 自动换行布局 | Wrap(children: [...]) |
| Spacer | 占位间隔 | Spacer(flex: 1) |
|
1 2 3 4 5 6 7 8 9 |
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.star), Icon(Icons.star), Icon(Icons.star), ], ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| children | List<Widget> | 子组件列表 |
| mainAxisAlignment | MainAxisAlignment | 主轴对齐 |
| crossAxisAlignment | CrossAxisAlignment | 交叉轴对齐 |
| mainAxisSize | MainAxisSize | 主轴占用空间(max/min) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Container( width: 200, height: 100, padding: EdgeInsets.all(10), margin: EdgeInsets.only(top: 20), alignment: Alignment.center, decoration: BoxDecoration( color: Colors.amber, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(color: Colors.grey, blurRadius: 4)], ), child: Text('我是容器'), ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| width / height | double | 宽高 |
| padding / margin | EdgeInsets | 内/外边距 |
| decoration | BoxDecoration | 背景、边框、阴影、圆角等 |
| alignment | Alignment | 子组件对齐方式 |
| child | Widget | 子组件 |
|
1 2 3 4 5 6 7 8 9 10 |
Stack( children: [ Container(width: 200, height: 200, color: Colors.green), Positioned( top: 20, left: 20, child: Container(width: 100, height: 100, color: Colors.red), ), ], ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| alignment | Alignment | 默认子组件对齐方式 |
| children | List<Widget> | 子组件列表 |
| fit | StackFit | 子组件如何填充 Stack |
CustomScrollView 滚动组件
复杂滚动页面,可组合多个 Sliver(静态+动态+吸顶)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
CustomScrollView( slivers: [ SliverToBoxAdapter(child: BannerWidget()), SliverToBoxAdapter(child: GridMenuWidget()), SliverPersistentHeader( pinned: true, delegate: StickyTabbarDelegate(), ), SliverStaggeredGrid.countBuilder( crossAxisCount: 2, itemCount: productList.length, itemBuilder: (context, index) => ProductItemWidget(product: productList[index]), staggeredTileBuilder: (index) => StaggeredTile.fit(1), ), ], ) |
| 组件 | 说明 | 示例代码 |
|---|---|---|
| AppBar | 页面顶部导航栏 | AppBar(title: Text("标题")) |
| BottomNavigationBar | 底部导航栏 | BottomNavigationBar(items: [...]) |
| Drawer | 抽屉菜单 | Drawer(child: ListView(...)) |
| TabBar / TabBarView | 顶部选项卡 | 配合 TabController 使用 |
| Navigator | 页面跳转 | Navigator.push(context, MaterialPageRoute(builder: (_) => Page())) |
| AlertDialog | 弹窗对话框 | showDialog(context: ..., builder: (_) => AlertDialog(...)) |
| GestureDetector | 手势识别 | GestureDetector(onTap: () { ... }) |
|
1 2 3 4 5 6 7 8 9 10 |
ListView.builder( itemCount: 10, itemBuilder: (context, index) { return ListTile( leading: Icon(Icons.person), title: Text('Person $index'), subtitle: Text('Subtitle $index'), ); }, ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| children | List<Widget> | 静态子组件列表 |
| itemBuilder | IndexedWidgetBuilder | 构建子项 |
| itemCount | int | 子项数量 |
| scrollDirection | Axis | 滚动方向(horizontal, vertical) |
|
1 2 3 4 5 6 7 8 9 10 11 |
GridView.count( crossAxisCount: 2, children: List.generate(4, (index) { return Center( child: Text( 'Item $index', style: Theme.of(context).textTheme.headline5, ), ); }), ) |
| 属性 | 类型 | 说明 |
|---|---|---|
| crossAxisCount | int | 横轴显示个数 |
| mainAxisSpacing | double | 主轴间距 |
| crossAxisSpacing | double | 横轴间距 |
| childAspectRatio | double | 宽高比 |
|
1 2 3 4 5 6 7 8 9 10 |
Card( elevation: 5, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Padding( padding: EdgeInsets.all(16), child: Text('This is a card'), ), ) |
| 组件 | 说明 | 示例代码 |
|---|---|---|
| TextField | 输入框 | TextField(decoration: InputDecoration(labelText: '姓名')) |
| TextFormField | 带验证的输入框 | TextFormField(validator: (val) => val!.isEmpty ? '必填' : null) |
| Form | 表单容器 | Form(key: _formKey, child: Column(...)) |
| Checkbox / CheckboxListTile | 复选框 | Checkbox(value: true, onChanged: ...) |
| Radio / RadioListTile | 单选框 | Radio(value: 1, groupValue: _val, onChanged: ...) |
| Switch | 开关 | Switch(value: true, onChanged: ...) |
| DropdownButton | 下拉菜单 | DropdownButton(items: [...], onChanged: ...) |
| Slider | 滑块 | Slider(value: 50, min: 0, max: 100, onChanged: ...) |
| 方案 | 描述 | 插件推荐 |
|---|---|---|
| 基于设计稿等比缩放 | 将 UI 尺寸按比例缩放适配 | flutter_screenutil |
| MediaQuery 自适应 | 读取设备尺寸并调整布局 | 内置 MediaQuery.of(context) |
| LayoutBuilder 自适应 | 按父容器的尺寸动态布局 | 内置 LayoutBuilder(...) |
| 响应式组件封装 | 根据屏幕宽度切换 UI | responsive_framework、flutter_responsive |
|
1 2 |
dependencies: flutter_screenutil: ^5.5.3+2 |
使用实例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() { runApp( ScreenUtilInit( designSize: Size(375, 812), // 设计稿尺寸(例如 iPhone X) builder: (context, child) => MyApp(), ), ); }
class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Container( width: 100.w, // 屏幕适配宽度 height: 100.h, // 屏幕适配高度 child: Text('Hello', style: TextStyle(fontSize: 16.sp)), // 字体大小适配 ), ), ); } } |
| 插件 | 功能 | 适合场景 |
|---|---|---|
| flutter_screenutil | 基于设计稿自动缩放 | 推荐用于大部分项目 |
| responsive_builder | 响应式断点布局 | 多平台(Web、Mobile)适配 |
| flutter_responsive_framework | 精准控制不同设备 UI | 企业级适配 |
| mediaquery_sizer | 类似 screenutil,但更轻量 | 轻量项目可用 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
lib/ ├─ main.dart # 程序入口 ├─ common/ # 公共工具、样式、API │ ├─ api.dart # 接口请求统一管理 │ ├─ constants.dart # 常量、枚举 │ ├─ utils/ # 工具类(日期、网络、加密等) │ └─ styles/ # 主题、颜色、字体、全局样式 │ ├─ widgets/ # 全局可复用组件(跨页面) │ ├─ custom_button.dart # 通用按钮 │ ├─ empty_view.dart # 空状态占位 │ ├─ loading_more.dart # 加载更多动画 │ └─ custom_appbar.dart # 顶部通用 AppBar │ ├─ pages/ # 页面模块 │ ├─ home/ # 首页模块 │ │ ├─ home_page.dart │ │ ├─ widgets/ # 仅首页专属组件 │ │ │ ├─ notice_bar.dart │ │ │ ├─ banner_carousel.dart │ │ │ ├─ menu_grid.dart │ │ │ ├─ waterfall_list.dart │ │ │ └─ tab_section.dart │ │ └─ home_controller.dart # 状态管理(Provider / Riverpod) │ │ │ ├─ product/ # 商品模块 │ │ ├─ product_page.dart │ │ ├─ widgets/ # 商品页面专属组件 │ │ │ ├─ product_card.dart │ │ │ ├─ product_filter.dart │ │ │ └─ product_banner.dart │ │ └─ product_controller.dart │ │ │ └─ mine/ # 个人中心模块 │ ├─ mine_page.dart │ └─ widgets/ │ └─ user_info_card.dart │ └─ routes/ # 路由统一管理 └─ app_routes.dart |
放项目全局可用的工具、常量、样式和接口
类似前端的 utils/ 或 services/
全局复用组件,不属于某个页面
例:按钮、加载动画、空状态组件
每个页面/模块独立一个目录
内部 widgets/ 只放该页面的专属组件
页面逻辑、状态管理、子组件都归属本模块
页面路由统一管理,便于导航和跳转