如何创建可扩展为两列的Widget列表实现笔记展示布局?
解决Flutter笔记双列布局动态添加问题
我想要实现笔记展示在屏幕部分区域的布局,用户可以创建笔记。目前已经完成部分实现,但存在问题:用了两个独立的列列表,添加笔记时只能放到其中一列里。以下是我的Flutter代码:
import 'package:flutter/material.dart'; void main() => runApp(HomePage()); class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Icon(Icons.menu), Text('Home'), Icon(Icons.search), ], ), Row( children: [ Padding( padding: const EdgeInsets.only(top: 25.0), child: Container( height: 500, child: const Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( children: [ NoteBlock(title: 'To Do List', content: 'fjskfjsk'), NoteBlock(title: 'Travelling', content: 'fjskfjsk'), NoteBlock(title: 'Travelling', content: 'fjskfjsk'), ], ), Column( children: [ NoteBlock(title: 'Travelling', content: 'fjskfjsk'), NoteBlock(title: 'Travelling', content: 'fjskfjsk'), NoteBlock(title: 'Travelling', content: 'fjskfjsk'), NoteBlock(title: 'Travelling', content: 'fjskfjsk'), ], ) ], ), ), ), ], ) ], ), )), )); } } class NoteBlock extends StatelessWidget { final String title; final String content; const NoteBlock({ super.key, required this.title, required this.content, }); @override Widget build(BuildContext context) { return Expanded( child: Padding( padding: const EdgeInsets.all(4.0), child: Container( color: const Color(0xFFF7F7F7), height: 100, width: MediaQuery.of(context).size.width / 2 - 30, child: Padding( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle(fontSize: 20), ), SizedBox(height: 20), Text(content), ], ), ), ), ), ); } }
优化方案:用GridView替代固定双列
硬编码两个Column的方式无法动态分配笔记到两列,改用GridView.count可以自动实现双列布局,新增笔记时直接往数据源里添加即可,无需手动管理列分配。
修改后的完整代码:
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: '笔记应用', home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { // 存储所有笔记的数据源 final List<Map<String, String>> _notes = [ {'title': 'To Do List', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, {'title': 'Travelling', 'content': 'fjskfjsk'}, ]; // 新增笔记方法 void _addNote() { setState(() { _notes.add({ 'title': '新笔记', 'content': '这是一条新添加的笔记内容', }); }); } @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( onPressed: _addNote, child: const Icon(Icons.add), ), body: SafeArea( child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: const [ Icon(Icons.menu), Text('Home', style: TextStyle(fontSize: 18)), Icon(Icons.search), ], ), // 笔记展示区域:GridView自动双列布局 Expanded( child: Padding( padding: const EdgeInsets.only(top: 25.0), child: GridView.count( crossAxisCount: 2, // 设置为双列 crossAxisSpacing: 10, // 列间距 mainAxisSpacing: 10, // 行间距 childAspectRatio: 1.5, // 卡片宽高比,可按需调整 children: _notes.map((note) { return NoteBlock( title: note['title']!, content: note['content']!, ); }).toList(), ), ), ), ], ), ), ), ); } } class NoteBlock extends StatelessWidget { final String title; final String content; const NoteBlock({ super.key, required this.title, required this.content, }); @override Widget build(BuildContext context) { return Container( color: const Color(0xFFF7F7F7), padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), ), const SizedBox(height: 10), Expanded( child: Text( content, overflow: TextOverflow.ellipsis, maxLines: 2, ), ), ], ), ); } }
关键修改说明
- 将
HomePage改为StatefulWidget,用于维护笔记列表的状态 - 用
GridView.count实现自动双列布局,新增笔记时直接向_notes列表添加数据即可,GridView会自动分配到对应列 - 移除
NoteBlock中固定的宽高和Expanded,由GridView统一控制卡片尺寸,布局更灵活 - 添加浮动按钮测试新增功能,点击即可生成新笔记
- 优化笔记卡片布局,内容超出时自动省略,避免溢出
内容的提问来源于stack exchange,提问作者Mikelenjilo
相关产品推荐
相关产品推荐

