在 Flutter 中随机显示图像
Randomize shown Images in Flutter
我想随机化显示的图像,并用布尔值检查,直到整副牌都被消耗掉,用过的“卡片”不再显示。
这是我的“卡片 class”,我在列表中指定了我的所有卡片:
import 'dart:math';
import 'dart:ui';
List<String> cardlist = [
'assets/images/card-1.png',
'assets/images/card-2.png',
'assets/images/card-3.png',
'assets/images/card-4.png',
'assets/images/card-5.png',
'assets/images/card-6.png',
'assets/images/card-7.png',
'assets/images/card-8.png',
'assets/images/card-9.png',
'assets/images/card-10.png',
'assets/images/card-11.png',
'assets/images/card-12.png',
'assets/images/card-13.png',
'assets/images/card-14.png',
'assets/images/card-15.png',
'assets/images/card-16.png',
'assets/images/card-17.png',
'assets/images/card-18.png',
'assets/images/card-19.png',
'assets/images/card-20.png',
'assets/images/card-21.png',
'assets/images/card-22.png',
'assets/images/card-23.png',
'assets/images/card-24.png',
'assets/images/card-25.png',
'assets/images/card-26.png',
'assets/images/card-27.png',
'assets/images/card-28.png',
'assets/images/card-29.png',
'assets/images/card-30.png',
'assets/images/card-31.png',
'assets/images/card-32.png',
'assets/images/card-33.png',
'assets/images/card-34.png',
'assets/images/card-35.png',
'assets/images/card-36.png',
'assets/images/card-37.png',
'assets/images/card-38.png',
'assets/images/card-39.png',
'assets/images/card-40.png',
'assets/images/card-41.png',
'assets/images/card-42.png',
'assets/images/card-43.png',
'assets/images/card-44.png',
'assets/images/card-45.png',
'assets/images/card-46.png',
'assets/images/card-47.png',
'assets/images/card-48.png',
'assets/images/card-49.png',
'assets/images/card-50.png',
'assets/images/card-51.png',
'assets/images/card-52.png',
'assets/images/card-53.png',
'assets/images/card-54.png',
'assets/images/card-55.png'
];
Random Randomizer = Random();
int randomIndex = random.nextInt(cardlist.length);
Image randomImage = cardlist[cardlist];
因为 Main.dart 上实际上只能显示 1 张卡片,点击时会翻转。我想在让它“丢弃”后显示一个新的,这是代码:
import 'package:flutter/material.dart';
import 'dart:math'; // wegen PI berechnung nötig
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//declare the isBack bool
bool isBack = true;
double angle = 0;
void _flip() {
setState(() {
angle = (angle + pi) % (2 * pi);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF292a3e),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: _flip,
child: TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: angle),
duration: Duration(seconds: 1),
builder: (BuildContext context, double val, __) {
//isBack wert wird geswithced
if (val >= (pi / 2)) {
isBack = false;
} else {
isBack = true;
}
return (Transform(
//Karte wird vom Center geflipped
alignment: Alignment.center,
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(val),
child: Container(
width: 309,
height: 474,
child: isBack
? Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: DecorationImage(
image: AssetImage("assets/images/back.png"),
),
),
) //Rückseite hier displayed
: Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..rotateY(
pi), // horizontaler flip
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0),
image: DecorationImage(
image: AssetImage("assets/images/card-1.png"),
),
),
child: Center(
child: Text(
"Hello You",
style: TextStyle(
fontSize: 30.0,
),
),
),
),
)
),
));
}),
)
],
),
),
),
);
}
}
对于初学者来说,您可以通过像这样声明该列表来节省一点屏幕空间。
final cardList =
List<String>.generate(55, (index) => 'assets/images/card-${index + 1}.png');
如果我理解你的问题,你只想生成一个随机图像并确保它们在全部使用之前不会从列表中重复,对吗?
如果是这样,我将复制该列表并处理它,并删除所有使用的条目。
List<String> availableImages = [...cardList]; // modifiable list
那么这个函数应该return一个没有被使用过的随机图片,如果它们都被使用过就重置列表。
AssetImage getRandomImage() {
if (availableImages.length == 0) {
availableImages = [...cardList]; // resetting if all images have been used
}
final random = Random();
int randomIndex = random.nextInt(availableImages.length);
final asset = availableImages[randomIndex];
availableImages.remove(asset); // removing image so it doesn't get used again until all images have been used
return AssetImage(asset);
}
然后您可以将 getRandomImage()
传递给您的 DecorationImage
而不是您现在拥有的硬编码值。
那至少应该让你朝着正确的方向前进。
根据@jamesdlin 的建议进行编辑
利用 Darts shuffle
方法你可以做这样的事情。
List<String> availableImages = [...cardList]..shuffle(); // shuffled copy of list
getRandomImage
可以这样实现。
int index = 0;
AssetImage getRandomImage() {
if (index == 54) {
availableImages.shuffle();
index = 0;
} // re-shuffling and resetting index if all images have been used
final asset = availableImages[index];
index++;
return AssetImage(asset);
}
我想随机化显示的图像,并用布尔值检查,直到整副牌都被消耗掉,用过的“卡片”不再显示。
这是我的“卡片 class”,我在列表中指定了我的所有卡片:
import 'dart:math';
import 'dart:ui';
List<String> cardlist = [
'assets/images/card-1.png',
'assets/images/card-2.png',
'assets/images/card-3.png',
'assets/images/card-4.png',
'assets/images/card-5.png',
'assets/images/card-6.png',
'assets/images/card-7.png',
'assets/images/card-8.png',
'assets/images/card-9.png',
'assets/images/card-10.png',
'assets/images/card-11.png',
'assets/images/card-12.png',
'assets/images/card-13.png',
'assets/images/card-14.png',
'assets/images/card-15.png',
'assets/images/card-16.png',
'assets/images/card-17.png',
'assets/images/card-18.png',
'assets/images/card-19.png',
'assets/images/card-20.png',
'assets/images/card-21.png',
'assets/images/card-22.png',
'assets/images/card-23.png',
'assets/images/card-24.png',
'assets/images/card-25.png',
'assets/images/card-26.png',
'assets/images/card-27.png',
'assets/images/card-28.png',
'assets/images/card-29.png',
'assets/images/card-30.png',
'assets/images/card-31.png',
'assets/images/card-32.png',
'assets/images/card-33.png',
'assets/images/card-34.png',
'assets/images/card-35.png',
'assets/images/card-36.png',
'assets/images/card-37.png',
'assets/images/card-38.png',
'assets/images/card-39.png',
'assets/images/card-40.png',
'assets/images/card-41.png',
'assets/images/card-42.png',
'assets/images/card-43.png',
'assets/images/card-44.png',
'assets/images/card-45.png',
'assets/images/card-46.png',
'assets/images/card-47.png',
'assets/images/card-48.png',
'assets/images/card-49.png',
'assets/images/card-50.png',
'assets/images/card-51.png',
'assets/images/card-52.png',
'assets/images/card-53.png',
'assets/images/card-54.png',
'assets/images/card-55.png'
];
Random Randomizer = Random();
int randomIndex = random.nextInt(cardlist.length);
Image randomImage = cardlist[cardlist];
因为 Main.dart 上实际上只能显示 1 张卡片,点击时会翻转。我想在让它“丢弃”后显示一个新的,这是代码:
import 'package:flutter/material.dart';
import 'dart:math'; // wegen PI berechnung nötig
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//declare the isBack bool
bool isBack = true;
double angle = 0;
void _flip() {
setState(() {
angle = (angle + pi) % (2 * pi);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF292a3e),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: _flip,
child: TweenAnimationBuilder(
tween: Tween<double>(begin: 0, end: angle),
duration: Duration(seconds: 1),
builder: (BuildContext context, double val, __) {
//isBack wert wird geswithced
if (val >= (pi / 2)) {
isBack = false;
} else {
isBack = true;
}
return (Transform(
//Karte wird vom Center geflipped
alignment: Alignment.center,
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(val),
child: Container(
width: 309,
height: 474,
child: isBack
? Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: DecorationImage(
image: AssetImage("assets/images/back.png"),
),
),
) //Rückseite hier displayed
: Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..rotateY(
pi), // horizontaler flip
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0),
image: DecorationImage(
image: AssetImage("assets/images/card-1.png"),
),
),
child: Center(
child: Text(
"Hello You",
style: TextStyle(
fontSize: 30.0,
),
),
),
),
)
),
));
}),
)
],
),
),
),
);
}
}
对于初学者来说,您可以通过像这样声明该列表来节省一点屏幕空间。
final cardList =
List<String>.generate(55, (index) => 'assets/images/card-${index + 1}.png');
如果我理解你的问题,你只想生成一个随机图像并确保它们在全部使用之前不会从列表中重复,对吗?
如果是这样,我将复制该列表并处理它,并删除所有使用的条目。
List<String> availableImages = [...cardList]; // modifiable list
那么这个函数应该return一个没有被使用过的随机图片,如果它们都被使用过就重置列表。
AssetImage getRandomImage() {
if (availableImages.length == 0) {
availableImages = [...cardList]; // resetting if all images have been used
}
final random = Random();
int randomIndex = random.nextInt(availableImages.length);
final asset = availableImages[randomIndex];
availableImages.remove(asset); // removing image so it doesn't get used again until all images have been used
return AssetImage(asset);
}
然后您可以将 getRandomImage()
传递给您的 DecorationImage
而不是您现在拥有的硬编码值。
那至少应该让你朝着正确的方向前进。
根据@jamesdlin 的建议进行编辑
利用 Darts shuffle
方法你可以做这样的事情。
List<String> availableImages = [...cardList]..shuffle(); // shuffled copy of list
getRandomImage
可以这样实现。
int index = 0;
AssetImage getRandomImage() {
if (index == 54) {
availableImages.shuffle();
index = 0;
} // re-shuffling and resetting index if all images have been used
final asset = availableImages[index];
index++;
return AssetImage(asset);
}