Flutter 基础控件速查(面向 Android 开发者)
目标:你是 Android 开发,快速上手 Flutter UI 与常用控件。示例均可直接复制到 Flutter 工程中尝试。
1. 快速对照表(Android → Flutter)
- 视图容器:View →
Container/SizedBox - 线性布局:LinearLayout(horizontal/vertical) →
Row/Column - 约束/叠放:FrameLayout / RelativeLayout →
Stack+Positioned,Align - 列表:RecyclerView →
ListView.builder/GridView.builder/CustomScrollView + Slivers - 文本:TextView →
Text - 图片:ImageView →
Image - 按钮:Button →
ElevatedButton/TextButton/IconButton - 输入框:EditText →
TextField - 顶部栏:Toolbar/ActionBar →
AppBar - 页面容器:Activity/Fragment →
Scaffold+ 路由(go_router)
2. 布局基础
2.1 线性布局:Row / Column
dart
Row(
children: [
const Icon(Icons.star),
const SizedBox(width: 8),
const Text('Row 示例'),
const Spacer(), // 占满剩余空间
ElevatedButton(onPressed: () {}, child: const Text('按钮')),
],
)
dart
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('标题', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
const SizedBox(height: 8),
const Text('副标题'),
],
)
2.2 约束与叠放:Container / SizedBox / Stack
dart
Container(
width: 200,
height: 120,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFFECECEC),
borderRadius: BorderRadius.circular(12),
),
child: const Text('Container 带圆角与内边距'),
)
dart
Stack(
children: [
Image.network('https://picsum.photos/400/200', width: double.infinity, height: 200, fit: BoxFit.cover),
const Positioned(
left: 12, bottom: 12,
child: Text('叠放文本', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
)
],
)
2.3 自适应:Expanded / Flexible / Wrap / Align / Center
dart
Row(
children: [
Expanded(child: Container(color: Colors.blue, height: 40)),
const SizedBox(width: 8),
Flexible(child: Container(color: Colors.orange, height: 40)),
],
)
3. 列表与滚动
3.1 ListView.builder
dart
ListView.builder(
itemCount: 20,
itemBuilder: (context, i) => ListTile(
leading: CircleAvatar(child: Text('$i')),
title: Text('Item $i'),
),
)
3.2 GridView.builder
dart
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, mainAxisSpacing: 8, crossAxisSpacing: 8, childAspectRatio: 0.75),
itemCount: 10,
itemBuilder: (context, i) => Container(color: Colors.grey.shade200),
)
3.3 Slivers(高级可选)
dart
CustomScrollView(
slivers: [
const SliverAppBar(pinned: true, title: Text('Sliver 列表示例')),
SliverList.builder(
itemCount: 50,
itemBuilder: (context, i) => ListTile(title: Text('Row $i')),
),
],
)
4. 文本、图片、图标
dart
const Text('Hello Flutter', style: TextStyle(fontSize: 16));
const Icon(Icons.settings, color: Colors.blue);
Image.asset('assets/images/common/logo.png', width: 48, height: 48);
Image.network('https://picsum.photos/200', fit: BoxFit.cover);
富文本(类似 Android Spannable):
dart
const RichText(
text: TextSpan(
text: 'Flutter ',
style: TextStyle(color: Colors.black),
children: [
TextSpan(text: '加粗', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' & '),
TextSpan(text: '变色', style: TextStyle(color: Colors.red)),
],
),
)
5. 按钮与手势
dart
ElevatedButton(onPressed: () {}, child: const Text('确定'));
TextButton(onPressed: () {}, child: const Text('取消'));
IconButton(onPressed: () {}, icon: const Icon(Icons.share));
点击水波与手势:
dart
InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(12),
child: const Padding(
padding: EdgeInsets.all(12),
child: Text('InkWell 点击区域'),
),
)
6. 输入与表单
dart
final TextEditingController controller = TextEditingController();
TextField(
controller: controller,
decoration: const InputDecoration(
hintText: '请输入内容',
border: OutlineInputBorder(),
),
)
表单校验:
dart
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
Form(
key: formKey,
child: Column(
children: [
TextFormField(
validator: (v) => (v == null || v.isEmpty) ? '必填' : null,
),
ElevatedButton(
onPressed: () {
if (formKey.currentState!.validate()) {
// 提交
}
},
child: const Text('提交'),
)
],
),
)
7. 页面结构与导航
基本页面结构:
dart
Scaffold(
appBar: AppBar(title: const Text('标题')),
body: const Center(child: Text('内容区')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
)
导航(项目使用 go_router,示例):
dart
// 注册路由(简化示例)
// context.go('/detail'); // 跳转
// context.pop(); // 返回
8. 状态管理(setState vs GetX)
原生 setState:
dart
int counter = 0;
setState(() => counter++);
GetX 响应式:
dart
class CounterController extends GetxController {
final RxInt count = 0.obs;
void increment() => count.value++;
}
// 使用:final c = Get.put(CounterController());
// Obx(() => Text('${c.count.value}'));
9. 弹窗与 BottomSheet
dart
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text('提示'),
content: const Text('确定吗?'),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
TextButton(onPressed: () {}, child: const Text('确定')),
],
),
);
dart
showModalBottomSheet(
context: context,
builder: (_) => SizedBox(
height: 240,
child: const Center(child: Text('BottomSheet')),
),
);
10. 适配与主题
屏幕适配(flutter_screenutil):
dart
// 入口处初始化 ScreenUtil,然后使用 12.w/12.h/12.sp 等
MediaQuery:
dart
final Size size = MediaQuery.of(context).size; // 屏幕尺寸
主题:
dart
ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
)
11. 网络(Dio 简例)
dart
final dio = Dio(BaseOptions(baseUrl: 'https://httpbin.org'));
final resp = await dio.get('/get');
项目内请优先使用 Retrofit + Service 层封装(参考现有 lib/src/services/**)。
12. 开发效率提示
- 热重载:保存文件即可热重载(尽量使用 const 构造减少重建)。
- 结构拆分:大组件拆小组件,避免深度嵌套。
- 代码生成:涉及数据模型/接口,记得运行
fvm flutter pub run build_runner build --delete-conflicting-outputs
13. 常见坑
- setState 与 Obx 混用:尽量让某块 UI 只监听一种状态来源,避免重复 rebuild。
- showModalBottomSheet 高度:默认按内容高度,想近全屏需
isScrollControlled: true+ 指定高度。 - iOS 跑不起来(Scheme/Flavor):需指定
--flavor与 Xcode 的 Scheme 对应。