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

Flutter点击单张图片切换时全部图片同步变更问题求解

问题根因

你当前所有按钮共用_ScreenState中定义的全局isReal变量,任意点击操作修改该变量后,所有依赖该变量的按钮都会同步重绘,因此出现全部图片一起切换的问题。

解决方案

最合理的实现方式是将单个按钮抽离为独立的StatefulWidget,让每个按钮自己维护自身的图片切换状态,互相之间完全隔离,修改成本也最低。

完整修改代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

class Screen extends StatefulWidget {
  @override
  _ScreenState createState() => _ScreenState();
}

class _ScreenState extends State<Screen> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            backgroundColor: Colors.teal[100],
            body: SafeArea(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  AnimalButton(
                    sound: 'cat.mp3',
                    color: Colors.red,
                    simpleImage: 'images/cat.png',
                    realImage: 'images/cat_real.jpg',
                  ),
                  Expanded(
                      child: Row(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                            AnimalButton(
                              sound: 'dog.mp3',
                              color: Colors.yellow,
                              simpleImage: 'images/dog.png',
                              realImage: 'images/cow.png',
                            ),
                            AnimalButton(
                              sound: 'cow.mp3',
                              color: Colors.orange,
                              simpleImage: 'images/cow.png',
                              realImage: 'images/dog.png',
                            ),
                          ])),
                  Expanded(
                      child: Row(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: <Widget>[
                            AnimalButton(
                              sound: 'pig.mp3',
                              color: Colors.green,
                              simpleImage: 'images/pig.png',
                              realImage: 'images/elephant.png',
                            ),
                            AnimalButton(
                              sound: 'elephant.mp3',
                              color: Colors.teal,
                              simpleImage: 'images/elephant.png',
                              realImage: 'images/rooster.png',
                            ),
                            AnimalButton(
                              sound: 'rooster.mp3',
                              color: Colors.blue,
                              simpleImage: 'images/rooster.png',
                              realImage: 'images/pig.png',
                            ),
                          ])),
                  Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: <Widget>[
                          AnimalButton(
                            sound: 'goat.mp3',
                            color: Colors.purple,
                            simpleImage: 'images/goat.jpg',
                            realImage: 'images/pig.png',
                          ),
                        ],
                      )),
                ],
              ),
            )));
  }
}

// 抽离为独立的有状态组件,自己管理自身的图片切换状态
class AnimalButton extends StatefulWidget {
  final String sound;
  final Color color;
  final String simpleImage;
  final String realImage;

  const AnimalButton({
    Key? key,
    required this.sound,
    required this.color,
    required this.simpleImage,
    required this.realImage,
  }) : super(key: key);

  @override
  State<AnimalButton> createState() => _AnimalButtonState();
}

class _AnimalButtonState extends State<AnimalButton> {
  // 每个按钮自己的isReal状态,和其他按钮完全隔离
  bool _isReal = true;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: FlatButton(
        onPressed: () {
          setState(() {
            _isReal = !_isReal;
          });
          final player = AudioCache();
          player.play(widget.sound);
        },
        color: widget.color,
        child: _isReal ? Image.asset(widget.simpleImage) : Image.asset(widget.realImage),
      ),
    );
  }
}

补充说明

如果不想抽离独立组件,也可以在父页面用Map或者List存储每个按钮对应的状态,点击时仅修改对应索引/标识的状态值即可,不过这种方案耦合度更高,后续维护成本比抽离组件的方案更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:36:03