Flutter中如何通过动画实现TextField获焦时动态放大的效果?
要实现TextField聚焦时平滑放大、同时隐藏侧边按钮的效果,你可以借助FocusNode监听输入框的聚焦状态,结合Flutter自带的动画组件实现过渡效果,具体实现方法如下:
步骤1:声明状态变量和聚焦监听
首先在对应页面的State类中添加如下代码,监听TextField的聚焦状态:
// 定义在State类中 late final FocusNode _textFieldFocusNode; bool _isTextFieldFocused = false; @override void initState() { super.initState(); _textFieldFocusNode = FocusNode(); // 监听聚焦状态变化 _textFieldFocusNode.addListener(() { setState(() { _isTextFieldFocused = _textFieldFocusNode.hasFocus; }); }); } @override void dispose() { // 销毁监听避免内存泄漏 _textFieldFocusNode.dispose(); super.dispose(); }
步骤2:修改原有布局代码,添加动画效果
替换你原有的Row布局代码,通过AnimatedContainer实现尺寸平滑过渡,同时控制侧边按钮的显隐:
Row( children: [ Expanded( child: AnimatedContainer( // 动画时长和过渡曲线可自行调整 duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, padding: EdgeInsets.only( // 聚焦时调整padding适配放大效果 top: _isTextFieldFocused ? 20 : 12, right: _isTextFieldFocused ? 8 : 18, left: 8 ), // 动态调整高度实现放大效果,数值可按需修改 height: _isTextFieldFocused ? 70 : 55, child: TextField( // 绑定我们自定义的FocusNode focusNode: _textFieldFocusNode, autofocus: false, style: TextStyle(fontSize: 22.0, color: Color(0xFFbdc6cf)), decoration: InputDecoration( filled: true, fillColor: Colors.white, hintText: 'Ara', contentPadding: const EdgeInsets.only( left: 14.0, bottom: 8.0, top: 8.0), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white), borderRadius: BorderRadius.circular(25.7), ), enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.white), borderRadius: BorderRadius.circular(25.7), ), // 可选:聚焦时右侧添加取消按钮,更符合示例目标效果 suffixIcon: _isTextFieldFocused ? IconButton( icon: const Icon(Icons.cancel, color: Colors.grey), onPressed: () => _textFieldFocusNode.unfocus(), ) : null, ), ), ), ), // 侧边按钮仅在未聚焦时显示,添加透明度过渡更自然 if(!_isTextFieldFocused) AnimatedOpacity( opacity: _isTextFieldFocused ? 0 : 1, duration: const Duration(milliseconds: 200), child: Row( children: [ Container( padding: EdgeInsets.only(top: 10), child: IconButton( onPressed: () { showDialog( context: context, builder: (BuildContext context) { return CustomDialogBox(); }); }, iconSize: 50, icon: SvgPicture.asset( "assets/images/addfolder.svg", width: 45, height: 45, ), color: Colors.white), ), Container( padding: EdgeInsets.only(top: 10), child: IconButton( onPressed: () { Navigator.of(context).pushNamed(Settings.routeName); }, iconSize: 50, icon: const Icon(Icons.settings), color: Colors.white), ), ], ), ) ], )
如果不需要隐藏侧边按钮、仅需要输入框本身放大,删掉上面控制按钮显隐的逻辑,仅保留AnimatedContainer的尺寸动态调整即可。
内容的提问来源于stack exchange,提问作者cvsrt
相关产品推荐
相关产品推荐

