试图在一个页面(和Class)中使用函数来控制或使用另一个页面中的函数
Trying to use Functions in one Page (and Class) to control or use Functions in another in Flutter
好的。所以我要展示一些代码,老实说我不知道为什么它不起作用。我只是觉得自己力不从心,这非常令人沮丧。
现在这不是我实际使用的程序,而是一个超级简单的示例程序,应该可以显示我遇到的问题。请不要让我将所有这些东西放入或放在一个函数或 class 中,因为这不是我的真实程序的选项,所以它不会解决我的实际问题。
所以在我的 main.dart 我有以下内容。
import 'package:flutter/cupertino.dart';
import 'dart:async';
import './page2.dart';
void main() => runApp(MyApp());
Page2 myPage = new Page2();
PageState myState = myPage.createState();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test 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 changeTest(dynamic function, context) async {
Timer.periodic(Duration (seconds: 2), (Timer t) {
myState.changeText();
counter++;
if (counter >= 10) {
t.cancel();
}
},);
Navigator.push(context, CupertinoPageRoute(builder: (context) => myPage));
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(myState.changeText, context),
),
),
);
}
}
在第二个 Dart 文件中我有
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import './main.dart';
class Page2 extends StatefulWidget {
@override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
textChanger = false;
setState(() {
});
} else {
print('Change Two');
textChanger = true;
setState(() {
});
}
} else {
firstText = false;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
}
现在这个程序做的是切换到第二页,然后停顿,没有任何反应。定时器正在被调用(我可以通过打印屏幕功能看到这一点)而且我可以看到文本应该改变,因为布尔值正在被适当地改变以这样做。
预期功能:我应该能够从我的主应用程序调用第二页的实例及其上的函数,并对第二页上的文本进行更改。
在我的真实应用程序中(要复杂得多,我不可能将其解析为适合此处的内容)我遇到了同样的问题。 (如果我在 Flutter 中使用热重载,我的实际应用程序中的文本会发生变化。)
如您所见,我正在尝试与跨 class 部门和跨职能部门进行沟通,但是要么 A) 我没有正确沟通,要么 B) 沟通不正确二级页面的实例,所以 setState() 调用没有在显示的变体上完成?这些是我唯一的猜测。
您不应该手动调用 createState。为了实现这样的事情,我更喜欢使用流来代替,这非常容易处理。
timerStream.dart
import 'dart:async';
class TimerStream {
StreamController _streamController;
StreamSink<bool> get timerSink =>
_streamController.sink;
Stream<bool> get timerStream =>
_streamController.stream;
TimerStream() {
_streamController = StreamController<bool>();
}
dispose() {
_streamController?.close();
}
}
main.dart
import 'dart:async';
import 'package:flutter/cupertino.dart';
import './page2.dart';
import './timerStream.dart';
void main() => runApp(MyApp());
TimerStream stream = TimerStream();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test 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 changeTest(context) async {
Navigator.push(context, CupertinoPageRoute(builder: (context) => Page2(stream: stream,)));
Timer.periodic(Duration (seconds: 5), (Timer t) {
stream.timerSink.add(true);
});
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(context),
),
),
);
}
}
page2.dart
import 'package:flutter/material.dart';
import 'timerStream.dart';
class Page2 extends StatefulWidget {
TimerStream stream;
Page2({this.stream});
@override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
setState(() {
textChanger = false;
});
} else {
print('Change Two');
setState(() {
textChanger = true;
});
}
} else {
firstText = false;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
@override
void initState() {
super.initState();
widget.stream.timerStream.listen((onData) {
changeText();
});
}
}
注意:如果需要,您可以切换值并在 page2 中使用它来更改文本,而不是将 true 写入流。
好的。所以我要展示一些代码,老实说我不知道为什么它不起作用。我只是觉得自己力不从心,这非常令人沮丧。
现在这不是我实际使用的程序,而是一个超级简单的示例程序,应该可以显示我遇到的问题。请不要让我将所有这些东西放入或放在一个函数或 class 中,因为这不是我的真实程序的选项,所以它不会解决我的实际问题。
所以在我的 main.dart 我有以下内容。
import 'package:flutter/cupertino.dart';
import 'dart:async';
import './page2.dart';
void main() => runApp(MyApp());
Page2 myPage = new Page2();
PageState myState = myPage.createState();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test 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 changeTest(dynamic function, context) async {
Timer.periodic(Duration (seconds: 2), (Timer t) {
myState.changeText();
counter++;
if (counter >= 10) {
t.cancel();
}
},);
Navigator.push(context, CupertinoPageRoute(builder: (context) => myPage));
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(myState.changeText, context),
),
),
);
}
}
在第二个 Dart 文件中我有
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import './main.dart';
class Page2 extends StatefulWidget {
@override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
textChanger = false;
setState(() {
});
} else {
print('Change Two');
textChanger = true;
setState(() {
});
}
} else {
firstText = false;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
}
现在这个程序做的是切换到第二页,然后停顿,没有任何反应。定时器正在被调用(我可以通过打印屏幕功能看到这一点)而且我可以看到文本应该改变,因为布尔值正在被适当地改变以这样做。
预期功能:我应该能够从我的主应用程序调用第二页的实例及其上的函数,并对第二页上的文本进行更改。
在我的真实应用程序中(要复杂得多,我不可能将其解析为适合此处的内容)我遇到了同样的问题。 (如果我在 Flutter 中使用热重载,我的实际应用程序中的文本会发生变化。)
如您所见,我正在尝试与跨 class 部门和跨职能部门进行沟通,但是要么 A) 我没有正确沟通,要么 B) 沟通不正确二级页面的实例,所以 setState() 调用没有在显示的变体上完成?这些是我唯一的猜测。
您不应该手动调用 createState。为了实现这样的事情,我更喜欢使用流来代替,这非常容易处理。
timerStream.dart
import 'dart:async';
class TimerStream {
StreamController _streamController;
StreamSink<bool> get timerSink =>
_streamController.sink;
Stream<bool> get timerStream =>
_streamController.stream;
TimerStream() {
_streamController = StreamController<bool>();
}
dispose() {
_streamController?.close();
}
}
main.dart
import 'dart:async';
import 'package:flutter/cupertino.dart';
import './page2.dart';
import './timerStream.dart';
void main() => runApp(MyApp());
TimerStream stream = TimerStream();
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return CupertinoApp(
title: 'Splash Test',
theme: CupertinoThemeData(
primaryColor: Color.fromARGB(255, 0, 0, 255),
),
home: MyHomePage(title: 'Splash Test 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 changeTest(context) async {
Navigator.push(context, CupertinoPageRoute(builder: (context) => Page2(stream: stream,)));
Timer.periodic(Duration (seconds: 5), (Timer t) {
stream.timerSink.add(true);
});
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: CupertinoButton(
child: Text('To Splash'),
onPressed: () => changeTest(context),
),
),
);
}
}
page2.dart
import 'package:flutter/material.dart';
import 'timerStream.dart';
class Page2 extends StatefulWidget {
TimerStream stream;
Page2({this.stream});
@override
State<StatefulWidget> createState() => new PageState();
}
class PageState extends State<Page2> {
bool textChanger = false;
bool firstText = true;
Text myText() {
if (textChanger) {
Text text1 = new Text('Text One',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
} else {
Text text1 = new Text('Text Two',
style: TextStyle(color: Color.fromARGB(255, 0, 0, 0)));
return text1;
}
}
void changeText() {
if (!firstText) {
if (textChanger) {
print('Change One');
setState(() {
textChanger = false;
});
} else {
print('Change Two');
setState(() {
textChanger = true;
});
}
} else {
firstText = false;
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Container(
child: Center(
child: myText()
)
),);
}
@override
void initState() {
super.initState();
widget.stream.timerStream.listen((onData) {
changeText();
});
}
}
注意:如果需要,您可以切换值并在 page2 中使用它来更改文本,而不是将 true 写入流。