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

Flutter问题:GridView.builder中仅让点击的ElevatedButton显示加载效果

解决GridView中单个按钮独立显示加载状态的问题

问题核心是你用了全局的单个_isLoading变量,点击任何按钮都会通过setState刷新整个列表,导致所有按钮都显示加载状态。要实现单个按钮独立控制,需要给每个网格项维护自己的加载状态:

步骤1:替换全局加载状态为列表/映射

把原来的单个bool _isLoading = false;替换为列表(按索引区分项)或映射(按唯一ID区分),用来记录每个项的加载状态:

// 假设你的网格数据源是List<YourItemModel> items;
List<bool> _loadingStates = [];

// 在initState中初始化,长度与数据源一致
@override
void initState() {
  super.initState();
  // items为你的网格数据源,初始化所有项为未加载状态
  _loadingStates = List.generate(items.length, (_) => false);
}

步骤2:修改点击方法,接收索引参数

更新_onSubmit方法,让它接收当前点击项的索引,只修改对应位置的加载状态:

void _onSubmit(int index) {
  if (Constants.USER_TOKEN != null && Constants.USER_TOKEN != '') {
    print('无需注册');
  } else {
    showDialog<void>(
      context: context,
      builder: (BuildContext dialogContext) {
        return SimpleDialog(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(18.0)),
          title: const Text(
            '请先完成注册,才能添加到购物车',
            textAlign: TextAlign.center,
          ),
          children: <Widget>[
            TextButton(
              child: const Text('去注册'),
              onPressed: () {
                Navigator.of(dialogContext).pop(); // 关闭弹窗
                Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(
                        builder: (context) => const MainScreen(currentIndex: 3)),
                    (route) => false);
              },
              style: ButtonStyle(alignment: Alignment.center),
            ),
          ],
        );
      },
    );
  }
  // 仅更新当前点击项的加载状态
  setState(() => _loadingStates[index] = true);
  Future.delayed(
    const Duration(seconds: 2),
    () => setState(() => _loadingStates[index] = false),
  );
}

步骤3:更新GridView中的按钮逻辑

在GridView.builder的itemBuilder里,根据当前索引获取对应的加载状态:

GridView.builder(
  // 其他配置参数...
  itemBuilder: (context, index) {
    return ElevatedButton.icon(
      icon: _loadingStates[index]
          ? Container(
              width: 24,
              height: 24,
              padding: const EdgeInsets.all(2.0),
              child: const CircularProgressIndicator(
                color: Colors.white,
                strokeWidth: 3,
              ),
            )
          : const Icon(Icons.shopping_basket),
      onPressed: () => _onSubmit(index),
      // 按钮其他属性...
    );
  },
)

补充说明

  • 如果你的网格项有唯一业务ID(如接口返回的id),可以改用Map<String, bool> _loadingStates = {};存储,初始化时给每个ID设置默认值false,点击时传入ID即可。
  • 若数据源动态更新(如下拉刷新),需同步更新_loadingStates的长度或内容,避免索引越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:01:13