flutter ontap正在调用整个小部件代码

qlvxas9a  于 2023-02-25  发布在  Flutter
关注(0)|答案(1)|浏览(136)

我有一个隐藏在像素矩阵下的图像,如下所示。

一旦你点击了任何颜色,它就会变成透明的。2因此,点击每一个像素都会显示隐藏在它下面的图像,如下所示。3实现这个的代码如下所示。

getAlmostRandomMatrix(size) {
    makeMatrix() => Iterable<List<Color>>.generate(
        size, (i) => List<Color>.filled(size, Colors.transparent)).toList();
    List<List<Color>> matrix = makeMatrix(); //size x size matrix with transparent colors as default
    int frequency = (size * size / 3)
        .toInt(); // this assumes that the size is a multiple of 3
    // else it will cause unequal distribution in the matrix
    List<int> distribution = [
      frequency,
      frequency,
      frequency
    ]; //this assumes that team size is 3

    Random random = Random();
    for (var i = 0; i < size; i++) {
      for (var j = 0; j < size; j++) {
        int rand = random.nextInt(3);
        if (distribution[rand] > 0) {
          switch (rand) {
            case 0:
              matrix[i][j] = Theme.of(context).colorScheme.secondary;
              break;
            case 1:
              matrix[i][j] = Theme.of(context).colorScheme.primary;
              break;
            case 2:
              matrix[i][j] = Theme.of(context).colorScheme.error;
              break;
            default:
              matrix[i][j] = Colors.transparent;
          }
          // matrix[i][j] = rand;
          distribution[rand] -= 1;
        } else {
          // brute force assignment to force equal frequency distribution
          // these colors won't be random anymore
          if (distribution[0] > 0) {
            matrix[i][j] = Theme.of(context).colorScheme.secondary;
            distribution[0] -= 1;
          } else if (distribution[1] > 0) {
            matrix[i][j] = Theme.of(context).colorScheme.primary;
            distribution[1] -= 1;
          } else {
            matrix[i][j] = Theme.of(context).colorScheme.error;
            distribution[2] -= 1;
          }
        }
      }
    }
    return matrix;
  }

  Widget paintPixelsOnReward() {
    int size = 9;
    List<List<Color>> matrix = getAlmostRandomMatrix(size);
    return Container(
        padding: const EdgeInsets.all(8.0),
        child: Stack(children: <Widget>[
          const Image(
            width: 360,
            height: 315,
            image: AssetImage('lib/assets/images/orange_butterfly_image.png'),
          ),
          Column(children: [
            for (int i = 0; i < size; i++)
              Row(
                children: [
                  for (int j = 0; j < size; j++) ...[
                    LayoutBuilder(
                      builder: (context, constraints) {
                        return Align(
                          alignment: Alignment.topLeft,
                          child: GestureDetector(
                              onTap: () {
                                // print(matrix);
                                setState(() {
                                  matrix[i][j] = Colors.transparent;
                                });
                              },
                              child: Container(
                                width: 40,
                                height: 35,
                                decoration: BoxDecoration(
                                    color: matrix[i][j],
                                    border: Border.all(
                                        width: 1, color: Colors.white)),
                              )),
                        );
                      },
                    ),
                  ]
                ],
              )
          ]),
        ]));
  }

然而,调用onTap并不像预期的那样工作。在点击一个特定的颜色元素时,它不是变成透明的,而是所有的像素再次随机化。看起来getAlmostRandomMatrix(size)在点击时再次被调用。有办法避免吗?
我试过将矩阵作为类级变量,但没有帮助。

okxuctiv

okxuctiv1#

状态管理很可能有问题。如果使用setState(),则可能会调用getAlmostRandomMatrix(),具体取决于您的代码(此代码段中未包含)。只需使用调试器确定是否如此。
是否只有在第一次构建小部件时才调用getAlmostRandomMatrix()?我猜,每个setState都会调用此方法。原因可能是在build()中调用或类似。

相关问题