我写了一个小应用程序,可以在启动屏幕上打印2
,3
,42
,HomePage
,然后等待2秒钟并完全切换到context
。我无法弄清楚如何在Widget之外使用Navigator的问题,因为它需要import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Stream<int> stream;
StreamController<int> myStreamController = StreamController();
void main() {
MyClass myClass = MyClass();
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft])
.then((_) {
runApp(new MyApp());
});
}
class MyClass {
MyClass() {
stream = Stream<int>.periodic(Duration(seconds: 1), (t) => t + 1).take(3);
myStreamController.addStream(stream).then(
(done) {
Future.delayed(Duration(seconds: 2), () { // wait 2 seconds before Showing HomePage
myStreamController.addStream( Stream.value(42) );
// Navigator.push(context, route) // But we do not have context in this class!!
});
}
);
// stream.pipe(myStreamController.sink);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: "Hello", routes: {
'/': (context) => SplashScreen(),
'/home': (context) => HomePage(),
});
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context)
{
return Scaffold(
appBar: AppBar(),
body: Container(
child: Text("Hello World, Home Page"),
),
);
}
}
class SplashScreen extends StatefulWidget {
@override
SplashScreenState createState() => SplashScreenState();
}
class SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 24,
color: Colors.black54
),
child: StreamBuilder(
stream: myStreamController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data) {
case 1:
return Text("${snapshot.data}");
case 2:
return Text("${snapshot.data}");
case 3:
return Text("${snapshot.data}");
default:
return Text("${snapshot.data}");
}
} else
return CircularProgressIndicator();
})
)
),
));
// return
}
}
class DigitProgressIndicator extends StatelessWidget
{
String text;
DigitProgressIndicator(this.text);
@override
Widget build(BuildContext context)
{
return Text(text);
}
}
。
这是我的代码:
{{1}}
答案 0 :(得分:0)
只需将其移动到显示42的位置即可
class SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 24,
color: Colors.black54
),
child: StreamBuilder(
stream: myStreamController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data) {
case 1:
return Text("${snapshot.data}");
case 2:
return Text("${snapshot.data}");
case 3:
return Text("${snapshot.data}");
default:
Navigator.push(context, route); // But now we have context in this class!!
return Text("${snapshot.data}");
}
} else
return CircularProgressIndicator();
})
)
),
));
// return
}
}
您还可以将Navigator
用Future.delayed
包裹起来,这样一来,它就会显示42。
也是一个提示:
Navigator
是一个小部件,不是管理类,Navigator.of(context)
将为您提供最接近的祖先Navigator
小部件。在pushing
小部件上Navigator
的脚手架意味着您要在具有Stack
个孩子的Scaffold
小部件之上添加小部件。
答案 1 :(得分:0)
我发现了两种从业务逻辑切换屏幕的方法。第一个(我认为最好)。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Stream<int> stream;
StreamController<int> myStreamController = StreamController.broadcast();
void main() {
MyClass myClass = MyClass();
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft])
.then((_) {
runApp(new MyApp());
});
}
class MyClass {
MyClass() {
stream = Stream<int>.periodic(Duration(seconds: 1), (t) => t + 1).take(3);
myStreamController.addStream(stream).then(
(done) {
Future.delayed(Duration(seconds: 2), () { // wait 2 seconds before Showing HomePage
myStreamController.addStream( Stream.value(42) );
});
}
);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: "Hello",
routes:
{
'/': (context) => SplashScreen(),
'/home': (context) => HomePage(),
},
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context)
{
return Scaffold(
appBar: AppBar(),
body: Container(
child: Text("Hello World, Home Page"),
),
);
}
}
class SplashScreen extends StatefulWidget {
@override
SplashScreenState createState() => SplashScreenState();
}
class SplashScreenState extends State<SplashScreen> {
@override
void initState() {
myStreamController.stream.listen((data) {
if (data == 42)
{
Navigator.pushNamed(context, '/home');
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 24,
color: Colors.black54
),
child: StreamBuilder(
stream: myStreamController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
switch (snapshot.data) {
case 1:
return Text("${snapshot.data}");
case 2:
return Text("${snapshot.data}");
case 3:
return Text("${snapshot.data}");
default:
return Text("${snapshot.data}");
}
} else
return CircularProgressIndicator();
})
)
),
));
}
}
此处介绍第二种方法http://stacksecrets.com/flutter/navigation-when-there-is-no-context