skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.


  2. Use StatefulWidget to handle the changes in IU

    class MyWidget extends StatefulWidget {
      const MyWidget({super.key});
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      List<int> numList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
      int value = 42;
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: nineCardsFixed(),
        );
      }
    
      List<Widget> nineCardsFixed() {
        List<Widget> output = [];
        for (int i = 0; i < numList.length; i++) {
          output.add(
            Card(
              child: InkWell(
                onTap: () {
                  setState(() {
                    value = i;
                  });
                  print('tapped! $value');
                },
                child: Container(
                  color: value == i ? Colors.blue : Colors.grey,
                  child: Text('element: ${numList.elementAt(i)}'),
                ),
              ),
            ),
          );
        }
        return output;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search