试图在一个页面(和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 写入流。