Метод setState () не обновляет пользовательский интерфейс (Flutter)

Мой домашний экран - это Scaffold с ListView в теле и плавающей кнопкой действия внизу. Кнопка действия переводит пользователя на второй экран, где он может ввести текст в поле ввода текста и нажать «Сохранить». Кнопка сохранения вызывает метод на главном экране, который добавляет текст в переменную List, на которой основан ListView. Проблема в том, что переменная List обновляется (я вижу в журнале), но setState не обновляет ListView. Что я делаю неправильно?

Вот код с главного экрана:

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

class Home extends StatefulWidget {
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {
    
    List lista = <Widget>[];

    void incrementLista(newItem) {
      print('$lista');
      setState(() {
        lista.add(Box('newItem'));
      });
    }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('List of Counters'),
        backgroundColor: Colors.deepPurple[1000],
      ),
      body: Builder(
        builder: (context)=>
       Center(
            child: ListView(children: lista),
          ),),
      floatingActionButton: FloatingActionButton(
          backgroundColor: Colors.grey[1000],
          onPressed: () {
            Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (context) => AddCounter(f: incrementLista)));
          },
          child: Icon(Icons.add, color: Colors.white)),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomNavigationBar(
        unselectedItemColor: Colors.grey[700],
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.list),
            title: Text('Lista'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.insert_chart),
            title: Text('Gráfico'),
          ),
        ],
        selectedItemColor: Colors.blue,
      ),
    );
  }
}

А вот код из addCounter.dart:

import 'package:flutter/material.dart';

class AddCounter extends StatefulWidget {
  final Function f;
  AddCounter({@required this.f});

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

class _AddCounterState extends State<AddCounter> {
  final myController = TextEditingController();

  @override
  void dispose() {
    myController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Add a counter'),
          backgroundColor: Colors.blue,
        ),
        body: Column(children: [
          Padding(
            padding: EdgeInsets.all(15),
            child: TextField(
              controller: myController,
              decoration: InputDecoration(
                  enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.blue, width: 2)),
                  hintText: 'Type a name for the counter'),
            ),
          ),
          RaisedButton(
            color: Colors.green,
            onPressed: () {
              widget.f(myController.text);
              Navigator.pop(context);
            },
            child: Text(
              'Save',
              style: TextStyle(color: Colors.white),
            ),
          )
        ]));
  }
}

Не думаю, что код виджета Box актуален. По сути, это карта с названием.


person gustgon1212    schedule 29.08.2020    source источник
comment
Также поделитесь кодом AddCounter.   -  person theCaptainXgod    schedule 29.08.2020
comment
lista - это список Widget? если это так, вам нужно создавать новый список каждый раз, когда вызывается setState   -  person pskink    schedule 29.08.2020
comment
Привет, @theCaptainXgod! Я только что поделился кодом AddCounter!   -  person gustgon1212    schedule 29.08.2020
comment
в основном вам не следует использовать такой список виджетов, слои данных и представления должны быть разделены, вместо этого вы должны использовать только список данных, см. flutter.dev/docs/cookbook/gestures/dismissible для получения дополнительной информации.   -  person pskink    schedule 29.08.2020
comment
Привет, @pskink, да, lista - это список настраиваемых виджетов с именем Box. Чтобы создать Box, я должен передать String в качестве аргумента.   -  person gustgon1212    schedule 29.08.2020
comment
поэтому используйте только список строк и создайте свои Boxes внутри build метода, проверьте ссылку, которую я опубликовал выше - они удаляют элементы списка, но идея та же   -  person pskink    schedule 29.08.2020
comment
@pskink, работает !!! Я застрял в этой проблеме несколько дней, не имея ни малейшего представления! Вы не представляете, насколько вы мне помогли, большое вам спасибо! Я не хочу злоупотреблять вашим терпением, но не могли бы вы объяснить мне, почему необходимо разделять уровни данных и представления?   -  person gustgon1212    schedule 29.08.2020
comment
это более или менее навязано дизайном флаттера под капотом   -  person pskink    schedule 29.08.2020


Ответы (1)


@pskink дал мне ответ, который отлично сработал. Вот:

в основном вам не следует использовать такой список виджетов, слои данных и представления должны быть разделены, вместо этого вы должны использовать только список данных, см. https://flutter.dev/docs/cookbook/gestures/dismissible для получения дополнительной информации.

person gustgon1212    schedule 29.08.2020