setState не работает с Navigator.of (контекст) - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь поиграть с флаттером Пример приложения часть 2 . В двух словах: Первая страница: он создает бесконечный список слов, где вы можете добавить / удалить некоторые из ваших любимых, и есть вторая страница, чтобы перечислить все любимые слова. Мы можем получить доступ ко второй странице через actions: <Widget>[IconButton(icon: Icon(Icons.list), onPressed: _pushSaved)] панели приложения

enter image description here

Я немного изменил код, чтобы вторая страница использовала тот же построитель списка _buildWordsList, поэтому они используют один и тот же макет / стиль, и мы также можем щелкнуть слова на второй странице, чтобы удалить их из списка.

К сожалению, когда я нажимаю на любимое слово на второй странице, хотя оно удаляет его из выбранные слова, он по-прежнему отображает (как это было все еще любимым)

Вот "важный" код ( и вот суть со всем кодом ):

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final List<WordPair> _saved = <WordPair>[]; // Add this line.
  # ...

  Widget _buildWordsList(WordPair itemAt(int index)) {
    return ListView.builder(
      ...
      itemBuilder: (BuildContext context, int i) {
        ...
        return _buildRow(item);
      },
    );
  }

  Widget _buildRow(WordPair pair) {

    return ListTile(
      title:  Text(pair),
      ...
      onTap: () {
        setState(() {
          if (alreadySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }

  WordPair _suggestionsBuilder(int index) {
    // ... fill suggestions if needed, then return related index suggestion
    return _suggestions[index];
  }

  WordPair _savedGetter(int index) {
    // ... check if index exists, return null if not
    return _saved[index];
  }

  void _pushSaved() {
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) {
          return Scaffold(
              appBar: AppBar(
                title: Text("Favorites suggestions"),
              ),
              body: _buildWordsList(_savedGetter));
        },
      ),
    );
  }

  @override // Add from this line ...
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
        actions: <Widget>[
          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved)
        ],
      ),
      body: _buildWordsList(_suggestionsBuilder),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}

В методе _pushSaved, который добавляет MaterialPageRoute, даже если я передаю контекст в Navigator.of(context).push(, когда я нахожусь на странице «Сохраненное предложение», и нажимаю на уже сохраненное предложение и строку onTaped срабатывает, второй список не перерисовывается. Но я уверен, что он удален из списка слов _saved, так как когда я возвращаюсь в общий список, он больше не выделяется (сердце больше не красное)

Итак, состояние изменено, но страница не похоже на подписку на изменения после загрузки / отправки. Он меняется только тогда, когда я go вернулся на домашнюю страницу и вернулся к сохраненным предложениям. Как я могу это исправить?

Спасибо за чтение. Я не знаю, куда обратиться за помощью. Есть ли какой-нибудь диссонанс / слабость для такого рода вещей?

1 Ответ

1 голос
/ 13 января 2020

Это не хорошая архитектура. Метод Navigazor.push() помещает виджеты в стек Navigator. Поскольку вы нигде не выталкиваете стек навигатора, они просто складываются. Вы должны добавить глобальную переменную, которая содержит данные о состоянии, и просто обновить пользовательский интерфейс с setState. Смотрите здесь для получения дополнительной информации: документация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...