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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:39