我是Flutter的新手,我使用以下工具创建了一个应用程序:
带有标题文本:'Count:'+ intCount的AppBar,其中intCount是全局整数。
另一个线程“工作”,每秒递增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标题文本不会更改:
答案 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。