samedi 29 août 2020

Flutter: getting switch toggle values from dynamic form or why does state change rebuild differs

I have kind of a form where I can add cards, each having 5 textfields and 2 switches. I would like to use a method to build the switch code (and the textfield code, but that is working). However, the switches refuse to show their intended state. I saw couple of similar questions. However, most were solved with a list view listing all switched/checkboxes next to one another (I have multiple cards with multiple textfields and multiple switches, each). This was close, but I don't really understand the answer (within the comments)

Actually some answers come up with the same (I guess more or less same because mine isn't working) code storing the switch state in a bool list. When debugging I can see that the values are correctly stored in the list. However, the changed value is not rendered upon state change.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  var descrTECs = <TextEditingController>[];
  var fixedSCs = [true]; //storing the switch values
  var cards = <Card>[]; // storing the list of cards with forms

  SizedBox createTextField(String placeholderStr, double fieldWidth) {
    var tFieldController = TextEditingController();
    switch (placeholderStr) { //switching placeholder to assign text controller to correct controller list
      case "Description":
        descrTECs.add(tFieldController);
        break;
    }
    return SizedBox(width: fieldWidth, height: 25,
      child: CupertinoTextField(
          placeholder: placeholderStr,
          controller: tFieldController,
      ),
    );
  }

  SizedBox createSwitch(int pos) {
    return SizedBox(width: 50, height: 25,
        child: CupertinoSwitch(
          value: fixedSCs[pos],
          onChanged: (value) {
            setState(() => fixedSCs[pos] = value); // value is stored in fixedSCs but not rendered upon rebuild
          },
        )
    );
  }

  Card createCard() {
    return Card(
      child: Row(children: <Widget>[
        Text('#p${cards.length + 1}:'),
        Column(
          children: <Widget>[
            createSwitch(cards.length),
            createTextField("Description", 70.0),
          ],),
      ],),
    );
  }

  @override
  void initState() {
    super.initState();
    cards.add(createCard()); // first card created upon start
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              child: ListView.builder( // List Builder to show all cards
                itemCount: cards.length,
                itemBuilder: (BuildContext context, int index) {
                  return cards[index];
                },
              ),
            ),
            RaisedButton(
                child: Text('add new'),
                onPressed: () => setState(() {
                  fixedSCs.add(true); // bool element created to create next card
                  cards.add(createCard());}  // create next card
                ),
              ),
          ],
        ),
      ),);
  }
}

One thing I do not understand in general: Upon rebuild after a state change cards.length} should be my number of cards, let's say 3. And when it renders the 1st card, it passes the line Text("#p${cards.length + 1}"), so it should show #p3 and not #p1. What do I get wrong here?




Aucun commentaire:

Enregistrer un commentaire