实现TextField聚焦时AppBar背景色从1%透明度黑色切换为纯黑色
实现TextField聚焦时AppBar背景色从1%透明度黑色切换为纯黑色
看起来你已经把UI的其他部分都搞定了,就差AppBar在输入框聚焦时的颜色切换对吧?我来给你捋个简单的实现思路,核心就是监听输入框的焦点状态,然后通知父页面更新AppBar的颜色。
第一步:在登录页面的State类里添加状态变量
先在_MyLoginPageState里定义一个布尔变量,用来标记是否有输入框处于聚焦状态,同时把AppBar的背景色和这个变量绑定:
class _MyLoginPageState extends State<MyLoginPage> { AppAssets appAssets = AppAssets(); bool _isInputFocused = false; // 新增状态变量,标记输入框是否聚焦 @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, appBar: AppBar( // 根据焦点状态切换颜色:聚焦时纯黑,否则1%透明黑 backgroundColor: _isInputFocused ? Colors.black : Colors.black.withOpacity(0.01), centerTitle: true, title: Text( 'Login', style: AppTextStyles.heading(), ), ), // ... 其他原有代码保持不变 ); } }
第二步:给MyInput组件添加焦点回调
因为你的MyInput是StatelessWidget,我们需要给它加一个回调函数,让它能把内部TextField的焦点变化通知给父页面。修改MyInput的代码:
class MyInput extends StatelessWidget { final String placeholder; // 新增焦点变化回调,用来通知父页面焦点状态 final void Function(bool)? onFocusChange; const MyInput({super.key, required this.placeholder, this.onFocusChange}); @override Widget build(BuildContext context) { // 创建FocusNode监听TextField的焦点状态 final focusNode = FocusNode(); // 添加焦点监听器 focusNode.addListener(() { // 把当前焦点状态传递给父页面 onFocusChange?.call(focusNode.hasFocus); }); return ClipRRect( borderRadius: borderRadius10, child: ConstrainedBox( constraints: const BoxConstraints( maxWidth: 350, maxHeight: 66.66, minWidth: 315, minHeight: 60, ), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: blur300, sigmaY: blur300), child: Container( decoration: BoxDecoration( color: backgroundColor.withOpacity(0.2), borderRadius: borderRadius10, ), child: TextField( focusNode: focusNode, // 将FocusNode绑定到TextField cursorColor: textPrimary, cursorOpacityAnimates: true, enableSuggestions: true, style: AppTextStyles.body(), decoration: InputDecoration( filled: true, fillColor: Colors.transparent, hintText: placeholder, hintStyle: AppTextStyles.body(), border: const OutlineInputBorder(borderSide: BorderSide.none)), ), ), ), ), ); } }
第三步:在父页面中给MyInput绑定回调
回到_MyLoginPageState的build方法里,使用MyInput时传入焦点变化的回调,触发状态更新:
ConstrainedBox( constraints: const BoxConstraints(maxHeight: 300, minHeight: 280), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ MyInput( placeholder: 'Username', onFocusChange: (isFocused) { setState(() { _isInputFocused = isFocused; }); }, ), MyInput( placeholder: 'Password', onFocusChange: (isFocused) { setState(() { _isInputFocused = isFocused; }); }, ), ], ), ),
为什么之前的surfaceTintColor和elevation没用?
因为你要改的是AppBar的背景色透明度,而surfaceTintColor是Material3中用来覆盖AppBar表面色调的属性,elevation是控制阴影高度的属性,这两个都和背景色的透明度切换无关,所以调整它们自然没效果啦。
这样改完之后,当你点击任意一个输入框聚焦时,AppBar就会变成纯黑色,失焦时回到1%透明的黑色,完全符合你的需求~
备注:内容来源于stack exchange,提问作者Param
相关产品推荐
相关产品推荐

