You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何实现类似WhatsApp点击附件后Container包裹软键盘的动画效果?

Flutter 完全可以实现 WhatsApp 同款软键盘附带动画容器的效果

实现核心思路

  • 首先禁用Scaffold默认的软键盘避让逻辑,将resizeToAvoidBottomInset设为false,完全自主控制底部区域的高度变化
  • 通过MediaQuery.of(context).viewInsets.bottom实时获取当前软键盘的高度,也可以使用flutter_keyboard_visibility第三方库监听键盘的显隐状态与高度变化
  • 用Flutter原生动画组件实现高度过渡:可选AnimatedContainer、AnimationController搭配SlideTransition等方案,过渡曲线选择Curves.easeInOut就可以还原WhatsApp的动画手感

核心逻辑说明

点击附件按钮时的交互逻辑:

  1. 若当前软键盘处于显示状态,先将底部附件容器的高度立刻设置为当前软键盘的高度,再触发输入框失焦收起软键盘,动画衔接过程几乎无感知,视觉上就是容器直接包裹住原软键盘的位置
  2. 若当前软键盘处于隐藏状态,直接控制附件容器高度在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 01:09:03