Попытка использовать функции на одной странице (и класс) для управления или использования функций на другой во флаттере - PullRequest
0 голосов
/ 31 января 2020

Хорошо. Итак, я собираюсь показать некоторый код, и я, честно говоря, не знаю, ПОЧЕМУ он не работает. Я просто чувствую, что я вне моей глубины, и это очень расстраивает.

Теперь это не та программа, над которой я на самом деле работаю, а очень простой пример программы, которая должна показать проблему, с которой я столкнулся. Пожалуйста, НЕ просите меня поместить все эти вещи в или внутри одной функции или класса, так как это НЕ вариант для моей настоящей программы, так что это не решит мою реальную проблему.

, поэтому в моем 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()
        ) 
      ),);
  }
}

Теперь эта программа переключается на вторую страницу, а затем останавливается, и ничего не происходит Таймер вызывается (я вижу это через функцию экрана печати) И я вижу, что текст ДОЛЖЕН изменяться, так как bools меняются должным образом.

Ожидаемая функциональность: я должен иметь возможность вызывать экземпляр второй страницы и функции на нем из моего основного приложения и вносить изменения в текст на этой второй странице.

В моем реальном приложении (гораздо сложнее, я не мог не возможно разобрать это на что-то, что будет соответствовать здесь) У меня та же проблема. (Если я использую горячую перезагрузку во Flutter, текст в моем реальном приложении изменится.)

Итак, как вы можете видеть, я пытаюсь общаться между классами и функциями, но либо А) неправильно взаимодействуете, или B) Связь с неверным экземпляром дополнительной страницы, и поэтому вызов setState () не выполняется в показанном варианте? Это мои единственные догадки.

1 Ответ

1 голос
/ 31 января 2020

Вы не должны вызывать 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. дротик

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();
    });
  }
}

Примечание. Если вы хотите, вместо записи в поток значения true, вы можете переключать значение и используйте это на своей странице2, чтобы изменить текст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...