Search code examples
flutterdartsetstate

Flutter/Dart: update some variables but not others when using setState()


I'm trying to improve my understanding of Flutter, and am struggling with an issue. I am trying to create an app that presents a list of cards which pull data from a list. There is a button on the bottom that creates a new card when the user clicks it.

I am trying to get each card to display a unique 'Round number'. So for example each time the user clicks the button, a card will be added that displays sequential numbers next to the word 'Round'. Round 1 > Round 2 > Round 3 and so on.

Right now everything works except that every time the button is pressed all the cards are updated with the latest number. And so instead of getting a sequential list of cards, every card is updated to the latest round number.

What am I doing wrong? Thank you.

Here is my code:


import 'package:flutter/material.dart';

class Round {

  int roundNumber;
  int firstNumber;
  int secondNumber;

  Round({ this.roundNumber, this.firstNumber, this.secondNumber, });

}

int uid = 1;

List<Round> roundsList = [
  Round(roundNumber: uid, firstNumber: 1, secondNumber: 2),
];


class createLevels extends StatefulWidget {
  @override
  _createLevelsState createState() => _createLevelsState();
}

class _createLevelsState extends State<createLevels> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
          title: Text("Create Rounds",)
      ),
      body: Padding(
        padding: const EdgeInsets.fromLTRB(20, 20, 20.0, 20),
        child: Container(
          child: Column(
              children: <Widget>[
                Expanded(
                  child: ListView.builder(
                    itemCount: roundsList.length,
                      itemBuilder: (BuildContext context, int whatIsThisVariable) {
                      return roundCard(Round(roundNumber: uid, firstNumber: 2, secondNumber: 3,));
                      }
                  ),
                ),
                Text("$roundsList"),
                RaisedButton(
                  onPressed: () {
                    uid++;
                    roundsList.add(Round(roundNumber: uid));
                    setState(() {});
                  },
                    child: Text("Add Round"),
                ),
              ],
          ),
        ),
      ),
    );
  }
}

class roundCard extends StatelessWidget {

  final Round round;

  roundCard(this.round);

  // roundsList.add(Round(roundNumber: 1));

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Card(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Spacer(
                  flex: 1,
                ),
                Expanded(
                  child: Text('Round ${round.roundNumber}:'),
                  flex: 12,
                ),
                Expanded(
                  child: TextFormField(
                      textAlign: TextAlign.center,
                      decoration: InputDecoration(
                        hintText: '${round.firstNumber}',
                      ),
                  ),
                  flex: 3,
                ),
                Spacer(
                  flex: 1,
                ),
                Expanded(
                  child: TextFormField(
                      textAlign: TextAlign.center,
                      decoration: InputDecoration(
                        hintText: '${round.secondNumber}',
                      ),
                  ),
                  flex: 3,
                ),
              ],
            ),
          )
      ),
    );
  }
}


Solution

  • You can copy paste run full code below
    You need to pass index not uid
    You can adjust first and second number you want

    code snippet

    itemBuilder: (BuildContext context, int index) {
                      return roundCard(roundsList[index]);
                    }),
    ...
    onPressed: () {
                      uid++;
                      firstNumber++;
                      secondNumber++;
                      roundsList.add(
                          Round(roundNumber: uid, firstNumber: firstNumber, secondNumber: secondNumber));
                      setState(() {});
                    }
    

    working demo

    enter image description here

    full code

    import 'package:flutter/material.dart';
    
    class Round {
      int roundNumber;
      int firstNumber;
      int secondNumber;
    
      Round({
        this.roundNumber,
        this.firstNumber,
        this.secondNumber,
      });
    }
    
    int uid = 1;
    int firstNumber = 2;
    int secondNumber = 3;
    
    List<Round> roundsList = [
      Round(roundNumber: uid, firstNumber: 1, secondNumber: 2),
    ];
    
    class createLevels extends StatefulWidget {
      @override
      _createLevelsState createState() => _createLevelsState();
    }
    
    class _createLevelsState extends State<createLevels> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
              centerTitle: true,
              title: Text(
                "Create Rounds",
              )),
          body: Padding(
            padding: const EdgeInsets.fromLTRB(20, 20, 20.0, 20),
            child: Container(
              child: Column(
                children: <Widget>[
                  Expanded(
                    child: ListView.builder(
                        itemCount: roundsList.length,
                        itemBuilder: (BuildContext context, int index) {
                          return roundCard(roundsList[index]);
                        }),
                  ),
                  Text("$roundsList"),
                  RaisedButton(
                    onPressed: () {
                      uid++;
                      firstNumber++;
                      secondNumber++;
                      roundsList.add(
                          Round(roundNumber: uid, firstNumber: firstNumber, secondNumber: secondNumber));
                      setState(() {});
                    },
                    child: Text("Add Round"),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    class roundCard extends StatelessWidget {
      final Round round;
    
      roundCard(this.round);
    
      // roundsList.add(Round(roundNumber: 1));
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Card(
              child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Spacer(
                  flex: 1,
                ),
                Expanded(
                  child: Text('Round ${round.roundNumber}:'),
                  flex: 12,
                ),
                Expanded(
                  child: TextFormField(
                    textAlign: TextAlign.center,
                    decoration: InputDecoration(
                      hintText: '${round.firstNumber}',
                    ),
                  ),
                  flex: 3,
                ),
                Spacer(
                  flex: 1,
                ),
                Expanded(
                  child: TextFormField(
                    textAlign: TextAlign.center,
                    decoration: InputDecoration(
                      hintText: '${round.secondNumber}',
                    ),
                  ),
                  flex: 3,
                ),
              ],
            ),
          )),
        );
      }
    }
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: createLevels(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }