我有一个隐藏在像素矩阵下的图像,如下所示。
一旦你点击了任何颜色,它就会变成透明的。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)
在点击时再次被调用。有办法避免吗?
我试过将矩阵作为类级变量,但没有帮助。
1条答案
按热度按时间okxuctiv1#
状态管理很可能有问题。如果使用setState(),则可能会调用getAlmostRandomMatrix(),具体取决于您的代码(此代码段中未包含)。只需使用调试器确定是否如此。
是否只有在第一次构建小部件时才调用getAlmostRandomMatrix()?我猜,每个setState都会调用此方法。原因可能是在build()中调用或类似。