Flutter Push 与 State 相关的视图
Flutter Push vs. State-related views
有两种方法可以更改用户在显示上看到的内容:我可以推送到另一个页面,或者我可以更改有状态小部件的状态并重建它。你能告诉我,哪种方式是最佳做法吗? (如果它取决于 - 我猜 - 取决于什么?)
推动:
class Pushing extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () => Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondPage())),)
),
);
}
}
使用状态
class UsingStates extends StatefulWidget {
@override
State createState() => new _UsingStatesState();
}
class _UsingStatesState extends State<UsingStates> {
bool isPageTwo;
@override
void initState() {
isPageTwo = false;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isPageTwo ? Center(child: Text('Page two')) : Center(child: RaisedButton(onPressed: () {
setState(() {
isPageTwo = true;
});
})),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Page1(title: 'Flutter Demo Home Page'),
);
}
}
class Page1 extends StatefulWidget {
Page1({Key key, this.title}) : super(key: key);
final String title;
@override
Page1State createState() => new Page1State();
}
class Page1State extends State<Page1> {
StreamController<int> streamController = new StreamController<int>();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new RaisedButton(child: new Text("This is Page 1, Press here to go to page 2"),onPressed:()=>streamController.add(2) ,),
),
);
}
@override
void initState() {
streamController.stream.listen((intValue){
print("Page 1 stream : "+intValue.toString());
if(intValue==2){
Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>Page2(title: "Page 2",)));
}
});
super.initState();
}
@override
void dispose() {
streamController.close();
super.dispose();
}
}
class Page2 extends StatefulWidget {
Page2({Key key, this.title}) : super(key: key);
final String title;
@override
Page2State createState() => new Page2State();
}
class Page2State extends State<Page2> {
StreamController<int> streamController = new StreamController<int>();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new RaisedButton(child: new Text("This is Page 2, Press here to go to page 2"),onPressed:()=> streamController.add(1),),
),
);
}
@override
void initState() {
streamController.stream.listen((intValue){
print("Page 2 stream : "+intValue.toString());
if(intValue==1){
Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>Page1(title: "Page 1",)));
}
});
super.initState();
}
@override
void dispose() {
streamController.close();
super.dispose();
}
}
抱歉格式错误。您可以 运行 此代码而无需任何依赖项。希望对您有所帮助
答案当然是:视情况而定。
何时使用Navigator
:
使用导航器推送的路线在某种程度上等同于...
Activity
和 Android 中的 Fragment
- Angular 或 React
中的路由
- 一个html个经典网页文件
您将使用 Navigator
在您应用程序的逻辑独立部分之间切换。想想带有不同页面的 Whosebug 应用程序,例如"Question List"、"Question Detail"、"Ask Question" 形式和 "User Profile".
Navigator
负责后退导航(android 手机上的硬件后退按钮 + AppBar
中的后退箭头)
请注意,路线不必覆盖整个屏幕。 showDialog
也在内部使用 Navigator.push()
(这就是为什么您使用 Navigator.pop()
关闭对话框。
类似于Android上的startActivityForResult
,路由也可以return调用pop
时的结果。考虑一个让您选择日期的对话框。
何时使用State
:
当屏幕是一个逻辑单元时使用State
,例如:
- 当您从服务器加载项目列表时,您将有 4 种不同的状态:
- 正在加载
- "An error occured..."
- 列表为空时显示的占位符
ListView
- 具有多个步骤的表单
- 具有多个选项卡的屏幕(在这种情况下,导航由选项卡栏处理)
- 在向服务器发送
POST
请求时 "Please wait" 覆盖屏幕阻塞屏幕
毕竟 Navigator
也是一个跟踪路线历史记录的 StatefulWidget
。有状态小部件是 Flutter 的基本构建块。当您的应用程序非常复杂且 Navigator
不符合您的需求时,您可以随时创建自己的 StatefulWidget
以实现完全控制。
查看 Flutter 的源代码(Android Studio 中的 CTRL + B)总是有帮助的。
有两种方法可以更改用户在显示上看到的内容:我可以推送到另一个页面,或者我可以更改有状态小部件的状态并重建它。你能告诉我,哪种方式是最佳做法吗? (如果它取决于 - 我猜 - 取决于什么?)
推动:
class Pushing extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () => Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondPage())),)
),
);
}
}
使用状态
class UsingStates extends StatefulWidget {
@override
State createState() => new _UsingStatesState();
}
class _UsingStatesState extends State<UsingStates> {
bool isPageTwo;
@override
void initState() {
isPageTwo = false;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isPageTwo ? Center(child: Text('Page two')) : Center(child: RaisedButton(onPressed: () {
setState(() {
isPageTwo = true;
});
})),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Page1(title: 'Flutter Demo Home Page'),
);
}
}
class Page1 extends StatefulWidget {
Page1({Key key, this.title}) : super(key: key);
final String title;
@override
Page1State createState() => new Page1State();
}
class Page1State extends State<Page1> {
StreamController<int> streamController = new StreamController<int>();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new RaisedButton(child: new Text("This is Page 1, Press here to go to page 2"),onPressed:()=>streamController.add(2) ,),
),
);
}
@override
void initState() {
streamController.stream.listen((intValue){
print("Page 1 stream : "+intValue.toString());
if(intValue==2){
Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>Page2(title: "Page 2",)));
}
});
super.initState();
}
@override
void dispose() {
streamController.close();
super.dispose();
}
}
class Page2 extends StatefulWidget {
Page2({Key key, this.title}) : super(key: key);
final String title;
@override
Page2State createState() => new Page2State();
}
class Page2State extends State<Page2> {
StreamController<int> streamController = new StreamController<int>();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new RaisedButton(child: new Text("This is Page 2, Press here to go to page 2"),onPressed:()=> streamController.add(1),),
),
);
}
@override
void initState() {
streamController.stream.listen((intValue){
print("Page 2 stream : "+intValue.toString());
if(intValue==1){
Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>Page1(title: "Page 1",)));
}
});
super.initState();
}
@override
void dispose() {
streamController.close();
super.dispose();
}
}
抱歉格式错误。您可以 运行 此代码而无需任何依赖项。希望对您有所帮助
答案当然是:视情况而定。
何时使用Navigator
:
使用导航器推送的路线在某种程度上等同于...
Activity
和 Android 中的 - Angular 或 React 中的路由
- 一个html个经典网页文件
Fragment
您将使用 Navigator
在您应用程序的逻辑独立部分之间切换。想想带有不同页面的 Whosebug 应用程序,例如"Question List"、"Question Detail"、"Ask Question" 形式和 "User Profile".
Navigator
负责后退导航(android 手机上的硬件后退按钮 + AppBar
中的后退箭头)
请注意,路线不必覆盖整个屏幕。 showDialog
也在内部使用 Navigator.push()
(这就是为什么您使用 Navigator.pop()
关闭对话框。
类似于Android上的startActivityForResult
,路由也可以return调用pop
时的结果。考虑一个让您选择日期的对话框。
何时使用State
:
当屏幕是一个逻辑单元时使用State
,例如:
- 当您从服务器加载项目列表时,您将有 4 种不同的状态:
- 正在加载
- "An error occured..."
- 列表为空时显示的占位符
ListView
- 具有多个步骤的表单
- 具有多个选项卡的屏幕(在这种情况下,导航由选项卡栏处理)
- 在向服务器发送
POST
请求时 "Please wait" 覆盖屏幕阻塞屏幕
毕竟 Navigator
也是一个跟踪路线历史记录的 StatefulWidget
。有状态小部件是 Flutter 的基本构建块。当您的应用程序非常复杂且 Navigator
不符合您的需求时,您可以随时创建自己的 StatefulWidget
以实现完全控制。
查看 Flutter 的源代码(Android Studio 中的 CTRL + B)总是有帮助的。