Flutter如何通过TextField与Button实现可滚动累计消息气泡功能
实现思路
- 采用
StatefulWidget维护动态状态,包含消息列表、输入框控制器两个核心状态 - 上方消息区域用
SingleChildScrollView嵌套Column实现滚动能力,消息气泡默认左对齐排列 - 底部输入区域用
Row包裹TextField和Add按钮,点击按钮时先做输入非空校验,符合条件则将内容加入消息列表并清空输入框
完整可运行示例代码
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '气泡笔记示例', theme: ThemeData(primarySwatch: Colors.blue), home: const MessageNotePage(), ); } } class MessageNotePage extends StatefulWidget { const MessageNotePage({super.key}); @override State<MessageNotePage> createState() => _MessageNotePageState(); } class _MessageNotePageState extends State<MessageNotePage> { final TextEditingController _textController = TextEditingController(); final List<String> _messageList = []; @override void dispose() { // 释放输入控制器,避免内存泄漏 _textController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('气泡笔记')), body: Column( children: [ // 上方消息列表区域,占满剩余高度 Expanded( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: _messageList.map((msg) { // 单个消息气泡样式 return Container( margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 14), decoration: BoxDecoration( color: Colors.blue.shade100, borderRadius: BorderRadius.circular(18), ), child: Text(msg, style: const TextStyle(fontSize: 15)), ); }).toList(), ), ), ), // 底部输入区域 Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: Colors.grey.shade100, border: Border(top: BorderSide(color: Colors.grey.shade300)), ), child: Row( children: [ Expanded( child: TextField( controller: _textController, decoration: InputDecoration( hintText: '请输入内容', border: OutlineInputBorder( borderRadius: BorderRadius.circular(24), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.white, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), ), ), ), const SizedBox(width: 8), ElevatedButton( style: ElevatedButton.styleFrom( shape: const CircleBorder(), padding: const EdgeInsets.all(12), ), onPressed: () { final inputContent = _textController.text.trim(); if (inputContent.isEmpty) return; setState(() { _messageList.add(inputContent); }); _textController.clear(); }, child: const Text('Add'), ), ], ), ), ], ), ); } }
关键逻辑说明
- 滚动能力实现:用
Expanded包裹SingleChildScrollView,可以让消息列表占用除底部输入栏外的所有剩余高度,内容超出屏幕高度时自动支持上下滚动 - 气泡左对齐:给消息列表外层的
Column设置crossAxisAlignment: CrossAxisAlignment.start,所有新增气泡都会默认在左上角排列 - 状态更新:新增消息时调用
setState触发UI重绘,自动渲染新增的气泡元素 - 输入校验:点击Add按钮时先对输入内容做去空校验,避免添加空白消息,添加完成后自动清空输入框,提升操作体验
内容的提问来源于stack exchange,提问作者Anthony Stephen Mendes
相关产品推荐
相关产品推荐

