如何在Flutter中使用setState而不进行用户交互

时间:2019-01-11 08:44:34

标签: flutter

我是Flutter的新手,我使用以下工具创建了一个应用程序:

  1. 带有标题文本:'Count:'+ intCount的AppBar,其中intCount是全局整数。

  2. 另一个线程“工作”,每秒递增intCount。 (我这样做是为了模拟:该应用程序中的某些[变量]可以通过例如socket.io通信进行更改,而无需任何用户交互)

所以,我的问题是,当intCount更改时,如何更改AppBar标题文本? (换句话说,我应该在哪里使用setState?)

我的main.dart如下:(可以通过在文件'pubspec.yaml'的'dependecies'下添加'threading:'来添加包线程,然后单击'Tools'->'Flutter'-> Android Studio中的“ Flutter软件包获取”

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

var intCount = 0;

void main() {
  var thread = new Thread(work);
  thread.start();

  runApp(mainApp());
}

class mainApp extends StatefulWidget {
  @override
  _MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<mainApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text(
              'Count: ' + intCount.toString()),
        ),
        body: HelloRectangle(),
      ),
    );
  }
}


work() async{
  print('Work Begins ...');
  while (true) {
    await Thread.sleep(1000);
    intCount += 1;
    print('Count: ' + intCount.toString());
  }
}


class HelloRectangle extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Colors.greenAccent,
        height: 300.0,
        width: 300.0,
        child: Center(
          child: Text(
            'Hello',
            style: TextStyle(fontSize: 40.0),
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );
  }
}

如下面的屏幕截图所示,intCount会按照控制台中的显示进行更改,但是AppBar标题文本不会更改:

enter image description here

1 个答案:

答案 0 :(得分:1)

对我来说,这很有效,不要从课外打电话,这里是解决方案。

int _count = 0;
  @override
  void initState() {
    var thread = new Thread(count);
    thread.start();
    _initData();
    super.initState();
  }

  void count() async {
    while (true) {
      setState(() {
        _count += 1;
      });
      await Thread.sleep(1000);
    }
  }
 appBar: AppBar(
          title: Text(_count.toString()),
        ),

上述Satish Soni先生提供的正确答案,我想在我的原始代码中包含以下答案:

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

var intCount = 0;

void main() {
  runApp(mainApp());
}

class mainApp extends StatefulWidget {
  @override
  _MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<mainApp> {
  @override
  void initState() {
    var thread = new Thread(work);
    thread.start();
    super.initState();
  }

  void work() async{
    print('Work Begins ...');
    while (true) {
      await Thread.sleep(1000);
      setState(() {
        intCount += 1;
      });
      print('Count: ' + intCount.toString());
    }
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text(
              'Count: ' + intCount.toString()),
        ),
        body: HelloRectangle(),
      ),
    );
  }
}

在包含Satish的答案后,正确的intCount将显示在控制台以及AppBar中。

根据我的理解,这意味着,通过使用Flutter,任何“有状态小部件外部世界中发生的事情”都不会反映在小部件内部。

为了让小部件外部的绑定变量发生问题时让小部件“重新呈现”自身,我尝试了以下解决方法:

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

var intCount = 0;

void main() {
  var thread = new Thread(work);
  thread.start();

  runApp(mainApp());
}

class mainApp extends StatefulWidget {

  @override
  _MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<mainApp> {
  @override
  void initState() {
    var thread2 = new Thread(work2);
    thread2.start();

    super.initState();
  }


  void work2() async{
    while (true) {
      await Thread.sleep(100);
      setState(() {
      });
    }
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text(
              'Count: ' + intCount.toString()),
        ),
        body: HelloRectangle(),
      ),
    );
  }
}



void work() async{
  print('Work Begins ...');
  while (true) {
    await Thread.sleep(1000);
    intCount += 1;
    print('Count: ' + intCount.toString());
  }
}


class HelloRectangle extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        color: Colors.greenAccent,
        height: 300.0,
        width: 300.0,
        child: Center(
          child: Text(
            'Hello',
            style: TextStyle(fontSize: 40.0),
            textAlign: TextAlign.center,
          ),
        ),
      ),
    );
  }
}

如您所见,线程“ work”更改了全局变量intCount,以模拟这种变量被窗口小部件外部的某些事物(可能是计时器/套接字/数据库等)更改的情况。

然后,我在小部件内使用另一个线程work2来每隔100毫秒自动“设置状态”。

好吧,我知道这很愚蠢,浪费资源,响应速度很慢(100毫秒)……但这也是我能想到的最佳解决方案。实际上,我正在尝试执行“动态绑定”(例如AngularJS中的操作)或“强制重新渲染”(例如App进入后台并在几分钟后返回,但发生了某些变化)之类的事情。

无论如何,再次感谢Satish Soni。