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
相关产品推荐
相关产品推荐

