Flutter : 我想在你点击图片的时候改变一张图片,其他人不受点击的影响
Flutter : I want to change an image when you tap the image, and others are not affected by the tap
我正在用 Flutter 创建一个简单的应用程序。 1 个屏幕上有 7 个图像。我需要一种功能,您可以在点击其中一张图像时更改图像。但是,现在当我点击一张图片时,其他 6 张图片也会发生变化。我创建了一个变量“isReal”以放入 buildButton() 中,“isReal”将在 For 语句中切换为真和假,该语句在 buildButton() 中切换为“isReal”。但是,那没有用。你能给我一些关于这个问题的建议吗?谢谢。
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> {
bool isReal = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
// appBar: AppBar(
// title: Text('AnimalSounds'), backgroundColor: Colors.teal),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('cat.mp3', Colors.red, 'images/cat.png',
'images/cat_real.jpg'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('dog.mp3', Colors.yellow, 'images/dog.png',
'images/cow.png'),
buildButton('cow.mp3', Colors.orange, 'images/cow.png',
'images/dog.png'),
])),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('pig.mp3', Colors.green, 'images/pig.png',
'images/elephant.png'),
buildButton('elephant.mp3', Colors.teal,
'images/elephant.png', 'images/rooster.png'),
buildButton('rooster.mp3', Colors.blue,
'images/rooster.png', 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('goat.mp3', Colors.purple, 'images/goat.jpg',
'images/pig.png'),
],
)),
],
),
)));
}
Expanded buildButton(sound, color, simpleImage, realImage) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: color,
child: isReal ? Image.asset(simpleImage) : Image.asset(realImage),
));
}
}
好的,您有变量 isReal
,整个 class 都相同(即每个按钮使用相同的变量)。因此,当您通过点击一个按钮更改它的值时,它也会影响所有其他按钮。
为了解决这个问题,我建议将按钮实现移到一个单独的 Statefull
小部件中。这样您就可以将 Screen
class 保持为 Stateless
.
更新:
显然你应该看一些关于如何自己制作的教程。但就目前而言,这是分离小部件后的样子。
我在这里做的是:
- 创建新小部件class
FlipButton
- 将代码从您的方法移至新小部件的构建函数中
- 给构造函数添加参数
这样每个 FlipButton
都有自己的 isReal
变量。
注意:我没有尝试编译它,所以可能会有一些错误。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//replace all occurances on `buildButton` method with new widget
FlipButton(sound: 'cat.mp3', color: Colors.red, simpleImage: 'images/cat.png', realImage: 'images/cat_real.jpg'),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'dog.mp3', color: Colors.yellow, simpleImage: 'images/dog.png', realImage: 'images/cow.png'),
FlipButton(sound: 'cow.mp3', color: Colors.orange, simpleImage: 'images/cow.png', realImage: 'images/dog.png'),
])),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'pig.mp3', color: Colors.green, simpleImage: 'images/pig.png', realImage: 'images/elephant.png'),
FlipButton(sound: 'elephant.mp3', color: Colors.teal, simpleImage: 'images/elephant.png', realImage: 'images/rooster.png'),
FlipButton(sound: 'rooster.mp3', color: Colors.blue, simpleImage: 'images/rooster.png', realImage: 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlipButton(sound: 'goat.mp3', color: Colors.purple, simpleImage: 'images/goat.jpg', realImage: 'images/pig.png'),
],
)),
],
),
),
),
);
}
}
/// You can copy this widget into separate file for better formatting
///
class FlipButton extends StatefulWidget {
//declare final variables
final String sound;
final Color color;
final String simpleImage;
final String realImage;
//constructor for this class
const FlipButton({
Key? key,
required this.sound,
required this.color,
required this.simpleImage,
required this.realImage,
}) : super(key: key);
@override
_FlipButtonState createState() => _FlipButtonState();
}
class _FlipButtonState extends State<FlipButton> {
//inside the state declare variable that is about to change
bool isReal = false;
@override
Widget build(BuildContext context) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: widget.color,
child: isReal ? Image.asset(widget.simpleImage) : Image.asset(widget.realImage),
));
}
}
您可以使用 dart:math 中的随机 class 来生成下一张随机图像。
例子:
int imageNumber = 1;
void updateImage() {
setState(() {
//Random.nextInt(n) returns random integer from 0 to n-1
imageNumber = Random().nextInt(7) + 1;
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: FlatButton(
child: Image.asset('images/dice$imageNumber.png'),
onPressed: () {
updateImage();
},
),
),
),
);
}
我正在用 Flutter 创建一个简单的应用程序。 1 个屏幕上有 7 个图像。我需要一种功能,您可以在点击其中一张图像时更改图像。但是,现在当我点击一张图片时,其他 6 张图片也会发生变化。我创建了一个变量“isReal”以放入 buildButton() 中,“isReal”将在 For 语句中切换为真和假,该语句在 buildButton() 中切换为“isReal”。但是,那没有用。你能给我一些关于这个问题的建议吗?谢谢。
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> {
bool isReal = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
// appBar: AppBar(
// title: Text('AnimalSounds'), backgroundColor: Colors.teal),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('cat.mp3', Colors.red, 'images/cat.png',
'images/cat_real.jpg'),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('dog.mp3', Colors.yellow, 'images/dog.png',
'images/cow.png'),
buildButton('cow.mp3', Colors.orange, 'images/cow.png',
'images/dog.png'),
])),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('pig.mp3', Colors.green, 'images/pig.png',
'images/elephant.png'),
buildButton('elephant.mp3', Colors.teal,
'images/elephant.png', 'images/rooster.png'),
buildButton('rooster.mp3', Colors.blue,
'images/rooster.png', 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildButton('goat.mp3', Colors.purple, 'images/goat.jpg',
'images/pig.png'),
],
)),
],
),
)));
}
Expanded buildButton(sound, color, simpleImage, realImage) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: color,
child: isReal ? Image.asset(simpleImage) : Image.asset(realImage),
));
}
}
好的,您有变量 isReal
,整个 class 都相同(即每个按钮使用相同的变量)。因此,当您通过点击一个按钮更改它的值时,它也会影响所有其他按钮。
为了解决这个问题,我建议将按钮实现移到一个单独的 Statefull
小部件中。这样您就可以将 Screen
class 保持为 Stateless
.
更新: 显然你应该看一些关于如何自己制作的教程。但就目前而言,这是分离小部件后的样子。
我在这里做的是:
- 创建新小部件class
FlipButton
- 将代码从您的方法移至新小部件的构建函数中
- 给构造函数添加参数
这样每个 FlipButton
都有自己的 isReal
变量。
注意:我没有尝试编译它,所以可能会有一些错误。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
class Screen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.teal[100],
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
//replace all occurances on `buildButton` method with new widget
FlipButton(sound: 'cat.mp3', color: Colors.red, simpleImage: 'images/cat.png', realImage: 'images/cat_real.jpg'),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'dog.mp3', color: Colors.yellow, simpleImage: 'images/dog.png', realImage: 'images/cow.png'),
FlipButton(sound: 'cow.mp3', color: Colors.orange, simpleImage: 'images/cow.png', realImage: 'images/dog.png'),
])),
Expanded(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[
FlipButton(sound: 'pig.mp3', color: Colors.green, simpleImage: 'images/pig.png', realImage: 'images/elephant.png'),
FlipButton(sound: 'elephant.mp3', color: Colors.teal, simpleImage: 'images/elephant.png', realImage: 'images/rooster.png'),
FlipButton(sound: 'rooster.mp3', color: Colors.blue, simpleImage: 'images/rooster.png', realImage: 'images/pig.png'),
])),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FlipButton(sound: 'goat.mp3', color: Colors.purple, simpleImage: 'images/goat.jpg', realImage: 'images/pig.png'),
],
)),
],
),
),
),
);
}
}
/// You can copy this widget into separate file for better formatting
///
class FlipButton extends StatefulWidget {
//declare final variables
final String sound;
final Color color;
final String simpleImage;
final String realImage;
//constructor for this class
const FlipButton({
Key? key,
required this.sound,
required this.color,
required this.simpleImage,
required this.realImage,
}) : super(key: key);
@override
_FlipButtonState createState() => _FlipButtonState();
}
class _FlipButtonState extends State<FlipButton> {
//inside the state declare variable that is about to change
bool isReal = false;
@override
Widget build(BuildContext context) {
return Expanded(
child: FlatButton(
onPressed: () {
setState(() {
isReal = !isReal;
});
final player = AudioCache();
player.play(sound);
},
color: widget.color,
child: isReal ? Image.asset(widget.simpleImage) : Image.asset(widget.realImage),
));
}
}
您可以使用 dart:math 中的随机 class 来生成下一张随机图像。 例子:
int imageNumber = 1;
void updateImage() {
setState(() {
//Random.nextInt(n) returns random integer from 0 to n-1
imageNumber = Random().nextInt(7) + 1;
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(50.0),
child: FlatButton(
child: Image.asset('images/dice$imageNumber.png'),
onPressed: () {
updateImage();
},
),
),
),
);
}