Flutter:无需StatefulWidget,实现按钮hover背景色切换
实现无StatefulWidget的BottomSheet按钮悬浮效果
问题分析
你的代码存在两个核心问题:
- 使用全局变量
isHover会导致所有按钮共享同一状态,鼠标悬停任意按钮时所有按钮都会切换背景色。 - 在非StatefulWidget的回调中调用
setState会报错,因为setState是State类的方法,无法直接在普通函数或StatelessWidget中使用。
解决方案:使用StatefulBuilder
无需创建单独的StatefulWidget,只需在每个按钮的作用域内使用StatefulBuilder,它能提供局部的状态管理能力,且不会增加额外的Widget层级复杂度。每个按钮将拥有独立的悬浮状态,互不干扰。
修正后的代码
import 'package:flutter/material.dart'; import 'package:pre/utility/static.data.dart'; import 'package:pre/utility/theme.dart'; import 'package:pre/widgets/custom_button.widget.dart'; import 'package:pre/widgets/social_widget/report-message.widget.dart'; void messageButtomSheet(BuildContext context, String text) { showModalBottomSheet( backgroundColor: Colors.transparent, context: context, builder: (builder) { return Container( height: ScreenUnit.heigh(context) * 8, decoration: const BoxDecoration( color: white, borderRadius: BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0), ), ), child: Padding( padding: const EdgeInsets.only( top: 30, left: 20, right: 20, bottom: 30, ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CustomIconButton( iconButton: Icons.close, iconsize: 20, color: secondarytextColor, ), const Text(''), const Text('') ], ), const Padding( padding: EdgeInsets.only(top: 4.0, bottom: 15), child: Text( '', style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold), ), ), Expanded( flex: 2, child: ListView.builder( itemCount: 4, itemBuilder: (context, index) { // 使用StatefulBuilder为每个按钮创建独立状态 return StatefulBuilder( builder: (context, setState) { bool isHover = false; return MouseRegion( onHover: (event) => setState(() => isHover = true), onExit: (event) => setState(() => isHover = false), child: customButtom( title: ' report', backgroundColor: isHover ? grey : white, fontColor: black, borderColor: black.withOpacity(0.5), height: ScreenUnit.heigh(context) * 0.067, margin: const EdgeInsets.only(bottom: 8), onPress: () {}, ), ); }, ); }, ), ), customButtom( title: 'تۆمارکردن', width: double.infinity, height: ScreenUnit.heigh(context) * 0.067, margin: const EdgeInsets.only(top: 20), onPress: () { ReportMessageButtomSheet(context, 'text'); }, ) ], ), ), ); }, ); }
关键改动说明
- 移除全局
isHover变量,将其移至StatefulBuilder内部,每个按钮拥有独立的状态。 - 使用
StatefulBuilder提供的setState方法更新局部状态,避免无状态环境下的报错。 - 简化
onHover和onExit的回调写法,使用箭头函数提升可读性。
内容的提问来源于stack exchange,提问作者rawa
相关产品推荐
相关产品推荐

