我是一个初学者在Flutter和我试图使新的项目乐趣:象棋钟。一旦其中一个按钮被按下,它应该开始运行,但它没有。请看一下,告诉我哪里做错了。试着指出它,而不是编码它,因为我不想只是复制和粘贴,而是把事情弄清楚。我猜一定是和变量作用域有关的东西。。下面是主.dart文件:
import 'package:flutter/material.dart';
import 'Clock.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: Chessclock(),
),
Expanded(
child: Chessclock(),
)
]
)))
);
}
}
字符串
下面是Clock.dart文件:
import 'dart:io';
import 'package:flutter/material.dart';
class Chessclock extends StatefulWidget {
final tim;
Chessclock({Key? key,required this.tim}): super({});
var minutes = this.tim~/60;
var seconds = this.tim % 60;
var inGame = false;
var dur = const Duration(seconds: 1);
void runtime(t,b){
if(b){
sleep(dur);
_tim--;
}else{
return;
}
}
bool inswitch(inGam){
return !inGam;
}
@override
State<Chessclock> createState() => new _ChessclockState();
}
class _ChessclockState extends State<Chessclock>{
@override
// TODO: implement runtimeType
Widget build(BuildContext context) {
runtime(tim,inGame);
return TextButton(
child: Text('$minutes:$seconds',
style: TextStyle(fontSize: 30)
),
onPressed: () {
setState(() {
inGame = inswitch(inGame);
});
},
style: TextButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: (inGame? Colors.green : Colors.grey),
)
);
}
}
型
我知道你会很好,因为Dart程序员都是很棒的人。:D个
2条答案
按热度按时间dtcbnfnu1#
所有这些东西都应该在_ChessclockState中:
字符串
此外,您可能需要使用状态生命周期方法,该方法将在第一次和创建小部件后触发一次:
型
你应该在state lyfecycle上深入研究https://flutterbyexample.com/lesson/stateful-widget-lifecycle#3-initstate
cld4siwp2#
首先,将
tim
声明为final是不合理的,因为您需要在您的案例中更新它的值。如果我没有误解你的意思,那么你实际上是想设置一个计时器(在你的情况下是
ChessClock
,它可以在触发时倒计时)对于倒计时逻辑,我们可以直接使用Dart中的
Timer.periodic
类来代替sleep()
,同时注意sleep()
的dart doc请小心使用,因为当隔离在睡眠调用中被阻塞时,无法在隔离中处理任何异步操作。
此外,在您的代码中,您希望调用state类中的
runtime()
方法,在我看来,如果您真的希望从状态访问小部件类的属性,则这将不起作用,IDE应该报告错误(在您的示例中,访问状态类_ChessclockState
中的Chessclock
中的runtime()
,您应该使用关键字widget
,例如您的状态类中的widget.runtime()
)另外,在代码的这一部分中
字符串
您使用setState调用
inswitch()
方法,该方法应处理倒数计时逻辑并每秒在ChessClock
中减少tim
,正如我上面提到的,代码中的倒数计时逻辑可能会因为使用sleep()
而导致一些问题让我们假设您已经修改了代码以使用
Timer
,并且倒计时逻辑工作良好,但是UI仍然不会像预期的那样每秒都改变。这是因为当在onPressed
回调中按下按钮时,您只调用了setState()
一次,但时间实际上是不断变化的。对于这个问题,有一个解决方案,您将倒计时逻辑移动到状态类中,然后您可以执行以下操作:
型
由于您可以在state类中访问
setState()
,现在您可以创建一个名为triggerCounting
的方法,每当widget.tim
更新时,该方法都会调用setState()
,此时UI应该每秒更新一次这里是完整的代码(注意,我的代码完全是一个新的应用程序,它创建了一个例子)
主省道
型
**时钟. dart **
型
我现在也在学习Flutter,可能我的解决方案不是最好的,实际上我的解决方案还存在一些问题,比如父部件无法直接访问计时器的值,注意不仅
ClockExample
需要访问并显示tim
的信息,应用的其他部分可能也需要知道倒计时的值,例如,应用程序可能需要停止游戏并显示对话框时,时间用完了,所以你可能需要考虑将状态拉到所有需要访问状态的小部件之上的小部件,或者你可以考虑使用一些状态管理包,如provider
(Provider on pub.dev)