如何在基于Flutter与DialogFlow的聊天机器人中添加建议按钮?
Flutter + DialogFlow 实现聊天机器人建议按钮方案
下面是针对需求的具体实现思路和代码示例,适合Flutter新手快速上手:
一、定义消息数据结构
首先创建一个ChatMessage类,用来存储每条聊天消息的内容、是否为用户消息,以及可选的建议按钮列表:
class ChatMessage { final String text; final bool isUserMessage; final List<String>? suggestions; ChatMessage({ required this.text, required this.isUserMessage, this.suggestions, }); }
二、从DialogFlow响应中提取建议按钮
调用DialogFlow API获取回复后,从响应结果里提取Suggestion Chips(DialogFlow中这类建议按钮通常在queryResult.fulfillmentMessages数组里,消息类型为suggestion),把提取到的建议文本绑定到ChatMessage的suggestions字段中:
// 假设已获取DialogFlow的响应对象response List<String> suggestions = []; for (var msg in response.queryResult.fulfillmentMessages) { if (msg.message == 'suggestion') { suggestions.addAll(msg.suggestions!.suggestions!.map((s) => s.title!)); } } // 将带建议的消息加入聊天列表 setState(() { _messages.add(ChatMessage( text: response.queryResult.fulfillmentText, isUserMessage: false, suggestions: suggestions.isNotEmpty ? suggestions : null, )); });
三、实现聊天UI,渲染建议按钮
在消息列表的Item组件中,判断当前消息是否携带建议按钮,若有则用Wrap组件(自动适配换行)渲染按钮组,点击按钮时直接发送对应文本到DialogFlow:
Widget _buildMessageItem(ChatMessage message) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), child: Column( crossAxisAlignment: message.isUserMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ // 消息气泡 Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: message.isUserMessage ? Colors.blueAccent : Colors.grey[200], borderRadius: BorderRadius.circular(16.0), ), child: Text( message.text, style: TextStyle( color: message.isUserMessage ? Colors.white : Colors.black, ), ), ), // 建议按钮组 if (message.suggestions != null && message.suggestions!.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 8.0), child: Wrap( spacing: 8.0, runSpacing: 8.0, children: message.suggestions!.map((suggestion) { return ElevatedButton( onPressed: () => _sendMessage(suggestion), style: ElevatedButton.styleFrom( backgroundColor: Colors.grey[100], foregroundColor: Colors.blueAccent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), ), child: Text(suggestion), ); }).toList(), ), ), ], ), ); }
四、完整聊天页面状态管理
用StatefulWidget维护聊天消息列表,实现消息发送的核心逻辑(包含模拟DialogFlow响应的示例,实际开发替换为真实API调用即可):
class ChatScreen extends StatefulWidget { const ChatScreen({super.key}); @override State<ChatScreen> createState() => _ChatScreenState(); } class _ChatScreenState extends State<ChatScreen> { final List<ChatMessage> _messages = []; final TextEditingController _textController = TextEditingController(); Future<void> _sendMessage(String text) async { // 添加用户消息到列表 setState(() { _messages.add(ChatMessage( text: text, isUserMessage: true, )); }); _textController.clear(); // 模拟DialogFlow返回带建议的响应(实际开发替换为真实API调用) await Future.delayed(const Duration(seconds: 1)); List<String> suggestions = text == 'Hello' ? ['Hi there!', 'What can I do for you?', 'Help'] : []; setState(() { _messages.add(ChatMessage( text: 'Welcome! How can I assist you?', isUserMessage: false, suggestions: suggestions.isNotEmpty ? suggestions : null, )); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Chat Bot')), body: Column( children: [ Expanded( child: ListView.builder( reverse: true, // 消息从底部向上滚动 itemCount: _messages.length, itemBuilder: (context, index) { return _buildMessageItem(_messages[_messages.length - 1 - index]); }, ), ), // 输入栏 Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ Expanded( child: TextField( controller: _textController, decoration: const InputDecoration( hintText: 'Type a message...', border: OutlineInputBorder( borderRadius: BorderRadius.circular(20.0), ), ), onSubmitted: _sendMessage, ), ), const SizedBox(width: 8.0), IconButton( icon: const Icon(Icons.send), onPressed: () => _sendMessage(_textController.text), ), ], ), ), ], ), ); } }
内容的提问来源于stack exchange,提问作者DavDo
相关产品推荐
相关产品推荐

