Search code examples
flutterdartstatefulwidget

Flutter StatefulWidget parameter unable to pass


I know there was a really similar case and got solved, I modified my code to 99% liked to that but somehow my list is undefined.

The list that is undefined is at the line where ' ...(list as List).map((answer) { '.

import 'package:flutter/material.dart';
import 'package:kzstats/common/AppBar.dart';
import 'package:kzstats/common/Drawer.dart';
import '../toggleButton.dart';

class Settings extends StatelessWidget {
  final String currentPage = 'Settings';
  static const _modes = [
    {
      'mode': ['KZTimer', 'SimpleKZ', 'Vanilla']
    },
    {
      'tickrate': [128, 102, 64]
    },
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: HomepageAppBar(currentPage),
        drawer: HomepageDrawer(),
        body: Padding(
          padding: EdgeInsets.all(8),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                buildHeader(
                  title: 'Mode',
                  child: ToggleButton(_modes[0]['mode']),
                ),
                SizedBox(height: 32),
                buildHeader(
                  title: 'Tick rate',
                  child: ToggleButton(_modes[1]['tickrate']),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Widget buildHeader({@required String title, @required Widget child}) => Column(
      children: [
        Text(
          title,
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 16),
        child,
      ],
    );

class ToggleButton extends StatefulWidget {
  final List<String> list;
  ToggleButton(this.list);

  @override
  State createState() => new _ToggleButtonState();
}

class _ToggleButtonState extends State<ToggleButton> {
  List<bool> _selections = [true, false, false];

  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.blue.shade200,
      child: ToggleButtons(
        isSelected: _selections,
        fillColor: Colors.lightBlue,
        color: Colors.black,
        selectedColor: Colors.white,
        renderBorder: false,
        children: <Widget>[
          ...(list as List<String>).map((answer) {
            return Padding(
              padding: EdgeInsets.symmetric(horizontal: 12),
              child: Text(
                answer,
                style: TextStyle(fontSize: 18),
              ),
            );
          }).toList(),
        ],
        onPressed: (int index) {
          setState(() {
            for (int i = 0; i < _selections.length; i++) {
              if (index == i) {
                _selections[i] = true;
              } else {
                _selections[i] = false;
              }
            }
          });
        },
      ),
    );
  }
}

In case someone needs the full code, it's available at https://github.com/davidp918/KZStats

I'm new to Flutter and stackoverflow so if anything please just comment, thanks!


Solution

  • We can access a variable of StatefulWidget from the state class using "widget" (for example: widget.list)

    Please refer below code sample for the reference.

    import 'package:flutter/material.dart';
    
    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,
              visualDensity: VisualDensity.adaptivePlatformDensity,
            ),
            home: Settings());
      }
    }
    
    class Settings extends StatelessWidget {
      final String currentPage = 'Settings';
      static const modes = [
        {
          'mode': ['KZTimer', 'SimpleKZ', 'Vanilla']
        },
        {
          'tickrate': [128, 102, 64]
        },
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SingleChildScrollView(
            child: Container(
              child: Padding(
                padding: EdgeInsets.all(8),
                child: Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      buildHeader(
                        title: 'Mode',
                        child: ToggleButton(modes[0]['mode']),
                      ),
                      SizedBox(height: 32),
                      buildHeader(
                        title: 'Tick rate',
                        child: ToggleButton(modes[1]['tickrate']),
                      ),
                      SizedBox(height: 32),
                      buildHeader(
                        title: 'Mode',
                        child: ToggleButton(modes[0]['mode']),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    
    Widget buildHeader({@required String title, @required Widget child}) {
      return Column(
        children: [
          Text(
            title,
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 16),
          child,
        ],
      );
    }
    
    class ToggleButton extends StatefulWidget {
      final List list;
      ToggleButton(this.list);
    
      @override
      State createState() => new _ToggleButtonState();
    }
    
    class _ToggleButtonState extends State<ToggleButton> {
      List<bool> _selections = [false, false, false];
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.blue.shade200,
          child: ToggleButtons(
            isSelected: _selections,
            fillColor: Colors.lightBlue,
            color: Colors.black,
            selectedColor: Colors.white,
            renderBorder: false,
            children: [
              ...(widget.list as List)?.map((answer) {
                return Padding(
                  padding: EdgeInsets.symmetric(horizontal: 12),
                  child: Text(
                    answer.toString() ?? '',
                    style: TextStyle(fontSize: 18),
                  ),
                );
              })?.toList(),
            ],
            onPressed: (int index) {
              setState(() {
                for (int i = 0; i < _selections.length; i++) {
                  if (index == i) {
                    _selections[i] = true;
                  } else {
                    _selections[i] = false;
                  }
                }
              });
            },
          ),
        );
      }
    }