Передать список в другой класс во Flutter - PullRequest
1 голос
/ 26 мая 2020

У меня есть список «имен» строк в NameViewList, и я пытаюсь передать его значения другому классу Basi c ().

Я пробовал этот подход, но он дает мне ошибку: error: 'names' является окончательным, и ему было присвоено значение при объявлении, поэтому его нельзя установить на новое значение. (final_initialized_in_declaration_and_constructor в [flutterspinningwheel] lib / nameviewlist.dart: 5)

Я использовал этот способ передачи переменной, и он работал, но когда я передаю список, он не работает

     class NameViewList extends StatefulWidget {
  NameViewList({Key key, this.names});
  final List<String> names = <String>[];

  @override
  _NameViewListState createState() => _NameViewListState();
}

class _NameViewListState extends State<NameViewList> {


  TextEditingController nameController = TextEditingController();

   createDialog(BuildContext context){
    return showDialog(context: context, builder: (context) {
      return AlertDialog(
        title: Text('Insert Name'),
        content: TextField(
          controller: nameController,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            labelText: 'Contact Name',
          ),
        ),
        actions: [
          MaterialButton(
            child: Text('Submit'),
            onPressed: (){
              addItemToList();
              Navigator.of(context).pop();
            },
          )
        ],
      );
    });
  }

  void addItemToList(){
    setState(() {
      widget.names.insert(0, nameController.text);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          IconButton(
            icon: Icon(Icons.queue, color: Colors.green,),
            onPressed: (){createDialog(context);},
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
          ),
          Row(
            children: [
              RaisedButton(
                child: Text('Clear'),
                onPressed: () {
                  setState(() {
                    widget.names.clear();

                  });
                },
              ),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(builder: (context)=> Basic(names: names)));
                },
              ),
            ],
          ),

Ответы [ 2 ]

2 голосов
/ 26 мая 2020

Измените эти строки:

  NameViewList({Key key, this.names});
  final List<String> names = <String>[];

To:

  NameViewList({List<String> names}) : this.names = names ?? [];
  final List<String> names;

Ваша проблема в том, что вы дважды устанавливаете переменную final со значением. Сначала вы устанавливаете пустой список строк. И затем вы устанавливаете его снова, если необязательный параметр (если необязательный параметр установлен в значение null).

Вместо этого мое решение меняет его, поэтому мы устанавливаем переменную names только один раз, сначала спрашивая если необязательный параметр равен нулю (не установлен), и если это так, мы устанавливаем значение в пустой список. В противном случае мы используем необязательный параметр.

0 голосов
/ 26 мая 2020

Вы не можете изменить переменную, если она объявлена ​​с помощью последнего конструктора. Итак, что вы можете сделать для решения вашей проблемы, так это создать другую переменную и присвоить ей значение final. Проблему можно решить вот так:

class NameViewList extends StatefulWidget {
  final List<String> names;
  NameViewList({Key key, this.names});

  @override
  _NameViewListState createState() => _NameViewListState();
}

class _NameViewListState extends State<NameViewList> {
  TextEditingController nameController = TextEditingController();
  List<String> names = <String>[];

  createDialog(BuildContext context) {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Insert Name'),
            content: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
            actions: [
              MaterialButton(
                child: Text('Submit'),
                onPressed: () {
                  addItemToList();
                  Navigator.of(context).pop();
                },
              )
            ],
          );
        });
  }

  void addItemToList() {
    setState(() {
      names.insert(0, nameController.text);
    });
  }

  @override
  void initState() {
    super.initState();
    names = widget.names;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Settings'),
        centerTitle: true,
      ),
      body: Column(
        children: [
          IconButton(
            icon: Icon(
              Icons.queue,
              color: Colors.green,
            ),
            onPressed: () {
              createDialog(context);
            },
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: TextField(
              controller: nameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Contact Name',
              ),
            ),
          ),
          Row(
            children: [
              RaisedButton(
                child: Text('Clear'),
                onPressed: () {
                  setState(() {
                    names.clear();
                  });
                },
              ),
              RaisedButton(
                child: Text('Submit'),
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) => Basic(names: names)));
                },
              ),
            ],
          )
        ],
      ),
    );
  }
}
...