Flutter如何实现类似WhatsApp点击附件后Container包裹软键盘的动画效果?
Flutter 完全可以实现 WhatsApp 同款软键盘附带动画容器的效果
实现核心思路
- 首先禁用Scaffold默认的软键盘避让逻辑,将
resizeToAvoidBottomInset设为false,完全自主控制底部区域的高度变化 - 通过
MediaQuery.of(context).viewInsets.bottom实时获取当前软键盘的高度,也可以使用flutter_keyboard_visibility第三方库监听键盘的显隐状态与高度变化 - 用Flutter原生动画组件实现高度过渡:可选
AnimatedContainer、AnimationController搭配SlideTransition等方案,过渡曲线选择Curves.easeInOut就可以还原WhatsApp的动画手感
核心逻辑说明
点击附件按钮时的交互逻辑:
- 若当前软键盘处于显示状态,先将底部附件容器的高度立刻设置为当前软键盘的高度,再触发输入框失焦收起软键盘,动画衔接过程几乎无感知,视觉上就是容器直接包裹住原软键盘的位置
- 若当前软键盘处于隐藏状态,直接控制附件容器高度在0和预设面板高度之间做动画切换即可
核心代码示例
import 'package:flutter/material.dart'; class ChatPage extends StatefulWidget { const ChatPage({super.key}); @override State<ChatPage> createState() => _ChatPageState(); } class _ChatPageState extends State<ChatPage> { double _attachmentPanelHeight = 0; static const _animDuration = Duration(milliseconds: 250); void _toggleAttachmentPanel() { final keyboardHeight = MediaQuery.of(context).viewInsets.bottom; if (keyboardHeight > 0) { // 软键盘显示中,先同步面板高度为键盘高度,再收起键盘 setState(() { _attachmentPanelHeight = keyboardHeight; }); FocusScope.of(context).unfocus(); } else { // 软键盘隐藏,直接切换面板显隐 setState(() { _attachmentPanelHeight = _attachmentPanelHeight > 0 ? 0 : 320; }); } } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: Column( children: [ // 聊天消息列表区域 const Expanded(child: Placeholder()), // 底部输入栏 Row( children: [ IconButton( onPressed: _toggleAttachmentPanel, icon: const Icon(Icons.attach_file), ), const Expanded(child: TextField()), IconButton(onPressed: () {}, icon: const Icon(Icons.send)), ], ), // 带动画的附件面板 AnimatedContainer( duration: _animDuration, curve: Curves.easeInOut, height: _attachmentPanelHeight, color: Colors.grey.shade100, child: GridView.count( padding: const EdgeInsets.all(16), crossAxisCount: 4, children: const [ Icon(Icons.photo, size: 40), Icon(Icons.camera_alt, size: 40), Icon(Icons.video_file, size: 40), Icon(Icons.document_scanner, size: 40), // 其他附件功能入口 ], ), ) ], ), ); } }
优化注意事项
- iOS端系统软键盘收起自带250ms左右的动画,把自定义动画的时长和系统动画对齐,衔接效果会更丝滑
- 如果需要更精细的动画匹配,可以监听系统键盘的动画进度,同步驱动附件面板的高度变化,还原度会更高
内容的提问来源于stack exchange,提问作者DolDurma
相关产品推荐
相关产品推荐

