I’ve been working in Dart for a little bit and tried to make a function that returned a list of cards. I wanted each card to change colors when it was tapped and I have a listener to make sure that happens. I tried streamlining the program as much as possible to make the program easier to read. In this case, when I iterate over a loop and use i
as a counter by increasing it at the end of every loop, the program does something I don’t want, using the current value of i
instead of its value when it is called. I was able to fix the problem by using a different loop type, but I have no idea why this changes anything.
Here is the original streamlined function:
List<Widget> nineCards() {
List<int> numList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<Widget> output = [];
int value = 42;
int i = 0;
for (int ele in numList) {
output.add(
Card(
child: InkWell(
onTap: () {
value = i;
print('tapped! $value');
},
child: Container(
color: value == i ? Colors.blue : Colors.grey,
child: Text('element: $ele'),
),
),
),
);
i++;
}
return output;
}
Here is the fixed version:
List<Widget> nineCardsFixed() {
List<int> numList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<Widget> output = [];
int value = 42;
for (int i = 0; i < numList.length; i++) {
output.add(
Card(
child: InkWell(
onTap: () {
value = i;
print('tapped! $value');
},
child: Container(
color: value == i ? Colors.blue : Colors.grey,
child: Text('element: ${numList.elementAt(i)}'),
),
),
),
);
}
return output;
}
And this is how I wanted to use the function:
void main() {
runApp(
const MaterialApp(
home: MyWidget(),
),
);
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: nineCardsFixed(),
);
}
}
2
Answers
as @pskink shared earlier, the following link answers my question: dart.dev/guides/language/language-tour#for-loops "Closures inside of Dart’s for loops capture the value of the index" as opposed to the index itself.
Use
StatefulWidget
to handle the changes in IU