Files
blog-press/docs/Web/Flutter/FlutterGuide.md
2026-05-20 11:26:38 +08:00

5.0 KiB
Raw Blame History

title, date
title date
Flutter基础教程 2025-12-05

应用核心Widget

// Flutter 应用的入口,配置主题、路由、国际化等。
MaterialApp(
  home: HomePage(),  // 必需:首页
  theme: ThemeData.light(),  // 主题
  routes: {'/details': (c) => DetailsPage()},  // 路由
  debugShowCheckedModeBanner: false,  // 隐藏调试条
)

// 页面骨架,包含顶部栏、内容区、悬浮按钮等标准组件。
Scaffold(
  appBar: AppBar(title: Text('标题')),  // 顶部栏
  body: Center(child: Text('内容')),     // 主体
  floatingActionButton: FloatingActionButton(
    onPressed: () {},  // 悬浮按钮
  ),
  drawer: Drawer(child: Text('侧边栏')),  // 抽屉
  bottomNavigationBar: BottomNavigationBar(
    items: [],  // 底部导航
  ),
)

布局Widget

Container(
  width: 100,
  height: 50,
  margin: EdgeInsets.all(10),  // 外边距
  padding: EdgeInsets.all(20),  // 内边距
  decoration: BoxDecoration(
    color: Colors.blue,  // 背景色
    borderRadius: BorderRadius.circular(10),  // 圆角
    border: Border.all(color: Colors.black),  // 边框
  ),
  child: Text('内容'),
)

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,  // 主轴对齐
  crossAxisAlignment: CrossAxisAlignment.center,  // 交叉轴对齐
  children: [Text('左'),Text('中'),Text('右')],
)

Column(
  children: [
    Expanded(child: Container(color: Colors.red)),  // 扩展
    Flexible(child: Container(color: Colors.blue)),  // 灵活
  ],
)

// 层叠布局,用于重叠显示 Widget配合 Positioned 定位。
Stack(
  children: [
    Container(color: Colors.red, width: 200, height: 200),  // 底层
    Positioned(  // 绝对定位
      top: 20,
      left: 20,
      child: Text('重叠内容'),
    ),
  ],
)

Row(
  children: [
    Text('左'),
    Spacer(),  // 自动占据剩余空间
    Text('右'),
  ],
)

Row(
  children: [
    Expanded(
      flex: 2,  // 权重
      child: Container(color: Colors.red),
    ),
    Expanded(
      flex: 1,
      child: Container(color: Colors.blue),
    ),
  ],
)

列表和网格

ListView(
  children: List.generate(20, (i) => ListTile(
    title: Text('项目 $i'),  // 列表项
  )),
)

// 懒加载版本(推荐)
ListView.builder(
  itemCount: 1000,
  itemBuilder: (context, index) => ListTile(
    title: Text('项目 $index'),
  ),
)

GridView.count(
  crossAxisCount: 2,  // 每行数量
  children: List.generate(20, (i) => Container(
    color: Colors.blue,
    child: Center(child: Text('$i')),
  )),
)

展示 Widget

Text(
  'Hello Flutter',
  style: TextStyle(
    fontSize: 20,
    color: Colors.blue,
    fontWeight: FontWeight.bold,
  ),
  textAlign: TextAlign.center,
)

Image.network(
  'https://example.com/image.jpg',
  width: 100,
  height: 100,
  fit: BoxFit.cover,  // 填充方式
  loadingBuilder: (c, child, progress) {
    if (progress == null) return child;
    return CircularProgressIndicator();
  },
)

Icon(
  Icons.favorite,
  color: Colors.red,
  size: 30,
)

对话框Widget

// 提示对话框showDialog 显示,需要 context。
showDialog(
  context: context,
  builder: (context) => AlertDialog(
    title: Text('提示'),
    content: Text('确定删除吗?'),
    actions: [
      TextButton(
        onPressed: () => Navigator.pop(context),
        child: Text('取消'),
      ),
      TextButton(
        onPressed: () => Navigator.pop(context),
        child: Text('确定'),
      ),
    ],
  ),
)

// 底部弹出表单
showModalBottomSheet(
  context: context,
  builder: (context) => Container(
    height: 200,
    child: ListView(
      children: [],
    ),
  ),
)

// 底部轻提示,不打断用户操作
ScaffoldMessenger.of(context).showSnackBar(
  SnackBar(
    content: Text('操作成功'),
    action: SnackBarAction(
      label: '撤销',
      onPressed: () {},
    ),
    duration: Duration(seconds: 2),
  ),
)

导航和路由

Navigator.push(  // 跳转
  context,
  MaterialPageRoute(builder: (c) => DetailsPage()),
);

Navigator.pop(context);  // 返回
Navigator.pushNamed(context, '/details');  // 命名路由

// 页面切换器
PageView(
  children: [
    Page1(),
    Page2(),
    Page3(),
  ],
  controller: PageController(),
  onPageChanged: (index) => print('切换到 $index'),
)

手势Widget

GestureDetector(
  onTap: () => print('点击'),
  onDoubleTap: () => print('双击'),
  onLongPress: () => print('长按'),
  onPanUpdate: (details) => print('拖拽: ${details.delta}'),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

InkWell(
  onTap: () => print('点击'),
  splashColor: Colors.blue.withOpacity(0.3),  // 水波纹颜色
  child: Container(
    padding: EdgeInsets.all(20),
    child: Text('可点击区域'),
  ),
)

其他Widget

// 控制 Widget 显示/隐藏,比条件渲染性能更好。
Visibility(
  visible: isVisible,  // 是否显示
  child: Text('内容'),
  maintainSize: true,  // 保持占位
  maintainAnimation: true,
  maintainState: true,
)