Panagiotis Iatrou
Panagiotis Iatrou

Reputation: 160

Flutter Switch widget does not work if created inside initState()

I am trying to create a Switch widget add it to a List of widgets inside the initState and then add this list to the children property of a Column in the build method. The app runs successfully and the Switch widget does show but clicking it does not change it as if it is not working. I have tried making the same widget inside the build method and the Switch works as expected.

I have added some comments in the _onClicked which I have assigned to the onChanged property of the Switch widget that show the flow of the value property.

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: App(),
  ));
}

class App extends StatefulWidget {
  @override
  AppState createState() => new AppState();
}

class AppState extends State<App> {

  List<Widget> widgetList = new List<Widget>();
  bool _value = false;

  void _onClicked(bool value) {
    print(_value); // prints false the first time and true for the rest
    setState(() {
      _value = value;
    });
    print(_value); // Always prints true
  }

  @override
  void initState() {
    Switch myWidget = new Switch(value: _value, onChanged: _onClicked);
    widgetList.add(myWidget);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('My AppBar'),
      ),
      body: new Container(
        padding: new EdgeInsets.all(32.0),
        child: new Center(
          child: new Column(children: widgetList),
        ),
      ),
    );
  }
}

Upvotes: 0

Views: 3073

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657536

initState is to initialize the state, not widgets. build is to create widgets.

There reason it fails is because the widgets needs to be rebuilt when the value changes (when you call setState), but it isn't because when build() is called, the previously (in initState) created widget is reused.

  @override
  Widget build(BuildContext context) {
    List<Widget> widgetList = [];
    Switch myWidget = new Switch(value: _value, onChanged: _onClicked);
    widgetList.add(myWidget);

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('My AppBar'),
      ),
      body: new Container(
        padding: new EdgeInsets.all(32.0),
        child: new Center(
          child: new Column(children: widgetList),
        ),
      ),
    );
  }

Upvotes: 3

Related Questions