Flutter setState () функция вызывается, но ничего не делает - PullRequest
0 голосов
/ 31 января 2020

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

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

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

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,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  bool textBool = false;

  void textChanger() {
    if (textBool) {
    setState(() {
      textBool = false;
    });
    } else {
      setState(() {
        textBool = true;
      });
    }
  }

  Text myText() {
    if (textBool) {
      Text newText = new Text('Original Text');
      return newText;
    } else {
      Text newText = new Text('New Text');
      return newText;
    }
  }


  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(
        child: myText(),          
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: stateModify,
        tooltip: 'Change Text',
      ), 
    );
  }
}

Future<void> stateModify() {

  Duration waitTimer = new Duration(seconds: 5);
  new Timer.periodic(waitTimer, (timer) {
    _MyHomePageState().textChanger();
    timer.cancel();
  });

}

Ожидаемая функциональность: нажмите кнопку, а через 5 секунд она должна перейти ко второму набору текста. Тогда я смогу снова нажать кнопку и переключить ее обратно.

Вместо этого в этом примере я получаю следующую ошибку:

[VERBOSE-2: ui_dart_state. cc (157) ] Необработанное исключение: setState () вызывается в конструкторе: _MyHomePageState # a5177 (состояние жизненного цикла: создано, виджет не установлен, не смонтирован)

И Google, похоже, не очень помогает в этом конкретном вопросе.

Есть предложения?

1 Ответ

2 голосов
/ 31 января 2020

Ваша stateModify функция не является методом _MyHomePageState. Также, когда вы обращаетесь к _MyHomePageState().textChanger() в stateModify, вы в конечном итоге создаете новый объект _MyHomePageState(), но не вставляете его в дерево визуализации.

Вы должны использовать Timer вместо Timer.periodic. Timer.periodic будет повторять задание до тех пор, пока не будет вызван Timer.cancel. Timer ответит вам по истечении заданного вами периода времени.

Передав функцию textChanger при вызове stateModify, вы сможете вызывать функцию _MyHomePageState без создания нового объекта.

Выполните следующие изменения.

floatingActionButton: FloatingActionButton(
        onPressed: ()=> stateModify(textChanger),
        tooltip: 'Change Text',
),

stateModify(dynamic function) {
   Timer(Duration(seconds: 5), function);
}
...