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

Flutter ListTile点击、hover颜色异常及onFocusChange跳转问题求助

问题解决方案

问题1:Hover颜色混乱、拖动时随机变色

核心原因是你使用了全局的isHovering变量,所有行共享同一个状态,导致hover或拖动时所有行的颜色同步变化,甚至出现随机异常。解决思路是给每一行维护独立的hover状态。

问题2:onFocusChange无法触发onClickRow

存在两个错误:

  • onFocusChange的回调类型是void Function(bool),你错误地返回了一个带bool?参数的嵌套函数;
  • onTap的写法不符合回调要求,onTap是无参回调,你却返回了一个带参数的函数。

修改后的完整代码

Widget generateReorderableList() {
  return Column(
    children: [
      Stack(
        children: [
          SizedBox(
            width: double.infinity,
            height: 600, // 需要调整的高度
            child: ReorderableListView(
              header: Column(
                children: [
                  Row(
                    children: [
                      for (final item in headersList)
                        Container(
                          padding: const EdgeInsets.all(19.0),
                          child: DefaultTextStyle(
                            style: const TextStyle(fontSize: 16.0),
                            child: item,
                          ),
                        ),
                    ],
                  ),
                  const CustomSeparator()
                ],
              ),
              onReorder: (int oldIndex, int newIndex) {
                handleDraggable(newIndex, oldIndex);
              },
              children: [
                for (final item in rowsList)
                  StatefulBuilder(
                    key: ValueKey(item),
                    builder: (context, setState) {
                      bool isItemHovering = false;
                      return InkWell(
                        onHover: (bool value) {
                          setState(() {
                            isItemHovering = value;
                          });
                        },
                        hoverColor: isItemHovering ? Colors.red : Colors.blue,
                        onTap: onClickRow != null
                            ? () => onClickRow!(item.item)
                            : null,
                        child: ListTile(
                          key: ValueKey(item),
                          title: Container(
                            padding: const EdgeInsets.only(left: 10.0),
                            child: DefaultTextStyle(
                              style: const TextStyle(
                                color: Colors.black,
                                fontSize: 14.0,
                              ),
                              child: item.widgets.first,
                            ),
                          ),
                          onFocusChange: onClickRow != null
                              ? (bool selected) => onClickRow!(item.item)
                              : null,
                          selected: item.selected ?? false,
                          mouseCursor: SystemMouseCursors.click,
                          hoverColor: isItemHovering ? Colors.yellow : Colors.green,
                        ),
                      );
                    },
                  ),
              ],
            ),
          ),
          if (button != null)
            Positioned(
              top: 12,
              right: 33,
              child: InkWell(
                onTap: button,
                child: MouseRegion(
                  cursor: SystemMouseCursors.click,
                  child: Container(
                    decoration: BoxDecoration(
                      color: Theme.of(context).colorScheme.surfaceVariant,
                      borderRadius: BorderRadius.circular(100),
                    ),
                    padding: const EdgeInsets.all(2),
                    child: const Align(
                      child: Icon(
                        Icons.add,
                        color: Colors.white,
                        size: 24,
                      ),
                    ),
                  ),
                ),
              ),
            )
        ],
      ),
      if (rowsList.isEmpty)
        const SizedBox(
          width: double.infinity,
          child: Text(
            'Aucune donnée',
            textAlign: TextAlign.center,
            style: TextStyle(fontStyle: FontStyle.italic),
          ),
        )
    ],
  );
}

关键修改说明

  1. 独立hover状态:用StatefulBuilder包裹每一行,给每个行创建专属的isItemHovering变量,hover时仅更新当前行的状态,彻底解决全局状态导致的颜色混乱。
  2. 修正onTap回调:onTap是无参回调,直接调用onClickRow!(item.item),删除多余的嵌套函数返回逻辑。
  3. 修正onFocusChange回调:回调参数类型改为bool(匹配官方定义),直接触发onClickRow,确保焦点变化时能正确执行跳转。
  4. 简化添加按钮代码:移除冗余的GestureDetector(InkWell已包含点击事件处理),精简代码结构。

内容的提问来源于stack exchange,提问作者Rodolphe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:14