将数据传递给 Flutter 中的有状态小部件
Passing Data to a Stateful Widget in Flutter
我想知道在创建有状态小部件时向其传递数据的推荐方法是什么。
我见过的两种款式是:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState(_server);
}
class _ServerInfoState extends State<ServerInfo> {
Server _server;
_ServerInfoState(Server server) {
this._server = server;
}
}
这个方法在ServerInfo
和_ServerInfoState
中都保留了一个值,有点浪费
另一种方法是使用widget._server
:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState();
}
class _ServerInfoState extends State<ServerInfo> {
@override
Widget build(BuildContext context) {
widget._server = "10"; // Do something we the server value
return null;
}
}
这似乎有点倒退,因为状态不再存储在 _ServerInfoSate
中,而是存储在小部件中。
有这方面的最佳实践吗?
不要使用它的构造函数将参数传递给 State
。
您应该只使用 this.widget.myField
.
访问参数
不仅编辑构造函数需要大量的手工工作;它没有带来任何东西。没有理由复制 Widget
.
的所有字段
编辑:
这是一个例子:
class ServerIpText extends StatefulWidget {
final String serverIP;
const ServerIpText ({ Key? key, this.serverIP }): super(key: key);
@override
_ServerIpTextState createState() => _ServerIpTextState();
}
class _ServerIpTextState extends State<ServerIpText> {
@override
Widget build(BuildContext context) {
return Text(widget.serverIP);
}
}
class AnotherClass extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: ServerIpText(serverIP: "127.0.0.1")
);
}
}
另一个答案,建立在@RémiRousselet 的答案和@user6638204 的问题上,如果你想传递初始值并仍然能够在以后的状态下更新它们:
class MyStateful extends StatefulWidget {
final String foo;
const MyStateful({Key key, this.foo}): super(key: key);
@override
_MyStatefulState createState() => _MyStatefulState(foo: this.foo);
}
class _MyStatefulState extends State<MyStateful> {
String foo;
_MyStatefulState({this.foo});
@override
Widget build(BuildContext context) {
return Text(foo);
}
}
用于传递初始值(不向构造函数传递任何内容)
class MyStateful extends StatefulWidget {
final String foo;
const MyStateful({Key key, this.foo}): super(key: key);
@override
_MyStatefulState createState() => _MyStatefulState();
}
class _MyStatefulState extends State<MyStateful> {
@override
void initState(){
super.initState();
// you can use this.widget.foo here
}
@override
Widget build(BuildContext context) {
return Text(foo);
}
}
最好的方法 是不要使用它的构造函数将参数传递给 State class。您可以使用 widget.myField
.
在状态 class 中轻松访问
例如
class UserData extends StatefulWidget {
final String clientName;
final int clientID;
const UserData(this.clientName,this.clientID);
@override
UserDataState createState() => UserDataState();
}
class UserDataState extends State<UserData> {
@override
Widget build(BuildContext context) {
// Here you direct access using widget
return Text(widget.clientName);
}
}
导航屏幕时传递数据:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => UserData("WonderClientName",132)));
@Rémi Rousselet、@Sanjayrajsinh、@Daksh Shah 也更好。但我也定义这是从开始 point.that 哪个参数是哪个值
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
String name = "Flutter Demo";
String description = "This is Demo Application";
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainActivity(
appName: name,
appDescription: description,
),
);
}
}
class MainActivity extends StatefulWidget {
MainActivity({Key key, this.appName, this.appDescription}) : super(key: key);
var appName;
var appDescription;
@override
_MainActivityState createState() => _MainActivityState();
}
class _MainActivityState extends State<MainActivity> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.appName),
),
body: Scaffold(
body: Center(
child: Text(widget.appDescription),
),
),
);
}
}
Flutter 的有状态小部件 API 有点尴尬:将数据存储在 Widget 中,以便在位于 State
对象中的 build()
方法中访问它 如果您不想使用一些更大的状态管理选项(Provider、BLoC),使用 flutter_hooks (https://pub.dev/packages/flutter_hooks) - 它是 SatefullWidget
s:
更好更干净的替代品
class Counter extends HookWidget {
final int _initialCount;
Counter(this._initialCount = 0);
@override
Widget build(BuildContext context) {
final counter = useState(_initialCount);
return GestureDetector(
// automatically triggers a rebuild of Counter widget
onTap: () => counter.value++,
child: Text(counter.value.toString()),
);
}
}
要将data
传递给有状态的小部件,首先,创建两个页面。现在从第一页打开第二页并传递数据。
class PageTwo extends StatefulWidget {
final String title;
final String name;
PageTwo ({ this.title, this.name });
@override
PageTwoState createState() => PageTwoState();
}
class PageTwoStateState extends State<PageTwo> {
@override
Widget build(BuildContext context) {
return Text(
widget.title,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700),
),
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialButton(
text: "Open PageTwo",
onPressed: () {
var destination = ServicePage(
title: '<Page Title>',
provider: '<Page Name>',
);
Navigator.push(context,
MaterialPageRoute(builder: (context) => destination));
},);
}
}
我想知道在创建有状态小部件时向其传递数据的推荐方法是什么。
我见过的两种款式是:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState(_server);
}
class _ServerInfoState extends State<ServerInfo> {
Server _server;
_ServerInfoState(Server server) {
this._server = server;
}
}
这个方法在ServerInfo
和_ServerInfoState
中都保留了一个值,有点浪费
另一种方法是使用widget._server
:
class ServerInfo extends StatefulWidget {
Server _server;
ServerInfo(Server server) {
this._server = server;
}
@override
State<StatefulWidget> createState() => new _ServerInfoState();
}
class _ServerInfoState extends State<ServerInfo> {
@override
Widget build(BuildContext context) {
widget._server = "10"; // Do something we the server value
return null;
}
}
这似乎有点倒退,因为状态不再存储在 _ServerInfoSate
中,而是存储在小部件中。
有这方面的最佳实践吗?
不要使用它的构造函数将参数传递给 State
。
您应该只使用 this.widget.myField
.
不仅编辑构造函数需要大量的手工工作;它没有带来任何东西。没有理由复制 Widget
.
编辑:
这是一个例子:
class ServerIpText extends StatefulWidget {
final String serverIP;
const ServerIpText ({ Key? key, this.serverIP }): super(key: key);
@override
_ServerIpTextState createState() => _ServerIpTextState();
}
class _ServerIpTextState extends State<ServerIpText> {
@override
Widget build(BuildContext context) {
return Text(widget.serverIP);
}
}
class AnotherClass extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: ServerIpText(serverIP: "127.0.0.1")
);
}
}
另一个答案,建立在@RémiRousselet 的答案和@user6638204 的问题上,如果你想传递初始值并仍然能够在以后的状态下更新它们:
class MyStateful extends StatefulWidget {
final String foo;
const MyStateful({Key key, this.foo}): super(key: key);
@override
_MyStatefulState createState() => _MyStatefulState(foo: this.foo);
}
class _MyStatefulState extends State<MyStateful> {
String foo;
_MyStatefulState({this.foo});
@override
Widget build(BuildContext context) {
return Text(foo);
}
}
用于传递初始值(不向构造函数传递任何内容)
class MyStateful extends StatefulWidget {
final String foo;
const MyStateful({Key key, this.foo}): super(key: key);
@override
_MyStatefulState createState() => _MyStatefulState();
}
class _MyStatefulState extends State<MyStateful> {
@override
void initState(){
super.initState();
// you can use this.widget.foo here
}
@override
Widget build(BuildContext context) {
return Text(foo);
}
}
最好的方法 是不要使用它的构造函数将参数传递给 State class。您可以使用 widget.myField
.
例如
class UserData extends StatefulWidget {
final String clientName;
final int clientID;
const UserData(this.clientName,this.clientID);
@override
UserDataState createState() => UserDataState();
}
class UserDataState extends State<UserData> {
@override
Widget build(BuildContext context) {
// Here you direct access using widget
return Text(widget.clientName);
}
}
导航屏幕时传递数据:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => UserData("WonderClientName",132)));
@Rémi Rousselet、@Sanjayrajsinh、@Daksh Shah 也更好。但我也定义这是从开始 point.that 哪个参数是哪个值
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
String name = "Flutter Demo";
String description = "This is Demo Application";
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainActivity(
appName: name,
appDescription: description,
),
);
}
}
class MainActivity extends StatefulWidget {
MainActivity({Key key, this.appName, this.appDescription}) : super(key: key);
var appName;
var appDescription;
@override
_MainActivityState createState() => _MainActivityState();
}
class _MainActivityState extends State<MainActivity> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.appName),
),
body: Scaffold(
body: Center(
child: Text(widget.appDescription),
),
),
);
}
}
Flutter 的有状态小部件 API 有点尴尬:将数据存储在 Widget 中,以便在位于 State
对象中的 build()
方法中访问它 如果您不想使用一些更大的状态管理选项(Provider、BLoC),使用 flutter_hooks (https://pub.dev/packages/flutter_hooks) - 它是 SatefullWidget
s:
class Counter extends HookWidget {
final int _initialCount;
Counter(this._initialCount = 0);
@override
Widget build(BuildContext context) {
final counter = useState(_initialCount);
return GestureDetector(
// automatically triggers a rebuild of Counter widget
onTap: () => counter.value++,
child: Text(counter.value.toString()),
);
}
}
要将data
传递给有状态的小部件,首先,创建两个页面。现在从第一页打开第二页并传递数据。
class PageTwo extends StatefulWidget {
final String title;
final String name;
PageTwo ({ this.title, this.name });
@override
PageTwoState createState() => PageTwoState();
}
class PageTwoStateState extends State<PageTwo> {
@override
Widget build(BuildContext context) {
return Text(
widget.title,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700),
),
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialButton(
text: "Open PageTwo",
onPressed: () {
var destination = ServicePage(
title: '<Page Title>',
provider: '<Page Name>',
);
Navigator.push(context,
MaterialPageRoute(builder: (context) => destination));
},);
}
}