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

Flutter 点击SVG切换颜色需两次点击问题排查与解决

问题根源

你定义的bool svgColourFilled = false是全局作用域变量,所有实例化的TwoSVGs组件都会共享这同一个变量值,导致两个组件的选中状态互相绑定:

  • 点击第一个组件将变量改为true,第一个组件变紫
  • 此时点第二个组件,第一次点击把变量改为false,两个组件都变灰,所以你会觉得第二个组件点了没反应
  • 第二次点击第二个组件变量改为true,两个组件都变紫,才会看到第二个组件有变化
修复方案

把全局的svgColourFilled变量移到_TwoSVGsState类内部作为私有成员变量,让每个TwoSVGs组件独立维护自己的选中状态,父组件代码无需修改,修改后的子组件代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class TwoSVGs extends StatefulWidget {
  final String? svgPicPath;
  final Color fillColour ;
  final Color emptyColour ;

  const TwoSVGs({
    Key? key, 
    this.svgPicPath, 
    this.fillColour = Colors.purple, 
    this.emptyColour= Colors.grey
  }) : super(key: key);

  @override
  State<TwoSVGs> createState() => _TwoSVGsState();
}

class _TwoSVGsState extends State<TwoSVGs> {
  // 状态变量放到State内部,每个组件实例独有一份
  bool _svgColourFilled = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(
          child: SizedBox(
            width : 80, 
            height : 80, 
            child: Material(
              color: Colors.transparent,
              child: InkWell(
                splashColor: Colors.white,
                onTap: () {
                  setState(() {  
                    _svgColourFilled = !_svgColourFilled;
                  });
                }, 
                child: FittedBox(
                  fit: BoxFit.contain,
                  child: SvgPicture.asset(
                    widget.svgPicPath!,
                    color: _svgColourFilled 
                      ? widget.fillColour
                      : widget.emptyColour
                  )
                )
              )
            )
          )
        )
      ]
    ); 
  } 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:06:03