在 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);
  }