我正在尝试在页面更改期间存储一些状态。因此,当重新加载页面时,旧数据值可用。
我一直在研究页面存储,但还没有弄清楚它是如何工作的。
我正在用PageStorage.of(context)?.writeState(context, 'Some text is here', identifier: ValueKey('test'));
写入存储,然后用back按钮卸载页面。
当我重新加载页面(使用Navigator.of(context).push()
时),使用PageStorage.of(context)?.readState(context, identifier: ValueKey('test'));
只会给我空值;
这是我写的一个简短的示例,用来演示我如何使用它。有人知道我做错了什么吗?
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
MyAppState createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
final PageStorageBucket _bucket = new PageStorageBucket();
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: PageStorage(
child: new MyHomePage(),
bucket: _bucket,
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
return new NewPage();
}));
},
),
);
}
}
class NewPage extends StatefulWidget {
NewPageState createState() => NewPageState();
}
class NewPageState extends State<NewPage> {
String _text = '';
@override
void initState() {
super.initState();
_text = PageStorage
.of(context)
?.readState(context, identifier: ValueKey('test'));
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: <Widget>[
Text('The text is $_text'),
FloatingActionButton(
onPressed: () {
setState(() {
PageStorage.of(context)?.writeState(
context, 'Some text is here',
identifier: ValueKey('test'));
});
},
)
],
),
);
}
}
最佳答案
您提供的代码有多个问题。
第一个是在你的MyAppState
中,你没有向你的key
提供PageStorage
。实际上,如果没有该键,则无法保存写入的数据,我引用:
WriteState(BuildContext上下文,动态数据,对象标识符)→void
包装:颤振
使用指定的标识符或根据给定上下文计算的标识符将给定数据写入此页存储桶。计算出的标识符基于从上下文到拥有此页面存储桶的页面存储小部件的路径中找到的pagestoragekey。
如果未提供显式标识符并且找不到pagestoragekey,则不会保存数据。
要解决这个问题,只需创建一个全局变量,并在创建您的变量时传递它:
class MyAppState extends State<MyApp> {
final PageStorageBucket _bucket = new PageStorageBucket();
@override
Widget build(context) {
return new MaterialApp(
home: PageStorage(
child: new MyHomePage(),
bucket: _bucket,
key: mykey,
),
);
}
}
然后再次使用相同的键写入数据:
onPressed: () {
setState(() {
PageStorage.of(context).writeState(context, 'Data saved',
identifier: ValueKey(mykey));
updateText();
});
最后,在我看来,更新文本的方法并不是最好的方法。
您应该创建一个方法(例如updateText())并在编写数据后调用它。
updateText() {
if (PageStorage.of(context) .readState(context, identifier: ValueKey(mykey)) != null) {
_text = PageStorage .of(context).readState(context, identifier: ValueKey(mykey));
}
else {
_text = 'PageStorageNull';
}
}
和往常一样,检查值是否为非空会更安全,以避免出现错误。
以下是完整代码:
void main() => runApp(new MyApp());
PageStorageKey mykey = new PageStorageKey("testkey");
class MyApp extends StatefulWidget {
@override
MyAppState createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
final PageStorageBucket _bucket = new PageStorageBucket();
@override
Widget build(context) {
return new MaterialApp(
home: PageStorage(
child: new MyHomePage(),
bucket: _bucket,
key: mykey,
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(context) {
return Center(
child: FloatingActionButton(
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new NewPage()));
},
),
);
}
}
class NewPage extends StatefulWidget {
NewPageState createState() => NewPageState();
}
class NewPageState extends State<NewPage> {
String _text;
@override
void initState() {
super.initState();
}
updateText() {
if (PageStorage.of(context) .readState(context, identifier: ValueKey(mykey)) != null) {
_text = PageStorage .of(context).readState(context, identifier: ValueKey(mykey));
}
else {
_text = 'PageStorageNull';
}
}
@override
Widget build(context) {
return Center(
child: Column(
children: <Widget>[
Text('The text is $_text'),
FloatingActionButton(
onPressed: () {
setState(() {
PageStorage.of(context).writeState(context, 'Data saved',
identifier: ValueKey(mykey));
updateText();
});
},
)
],
),
);
}
}
使用此代码,按按钮转到第二页。在第二页上,按按钮用
PageStorageKey mykey = new PageStorageKey("testkey");
方法中提供的数据更新文本。希望这能帮到你,
当做
编辑
先打事情,抱歉误解了要点。
实际上,你想要的是用桶。
实际上:
PageStorage
可以替换为:writeState()
所以你要做的是使你的
PageStorage .of(context).readState(context, identifier: ValueKey(mykey));
变量成为全局变量,然后你需要把你在_bucket.readState(context, identifier: ValueKey(mykey));
中的所有东西都包装在一个_bucket
中,使用与你在NewPageState
中的第一个PageStorage
相同的Key
和Bucket
这样,您也可以使用bucket读取数据,并通过导航保存数据。
他还是完整的代码:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
PageStorageKey mykey = new PageStorageKey("testkey");
final PageStorageBucket _bucket = new PageStorageBucket();
class MyApp extends StatefulWidget {
@override
MyAppState createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
@override
Widget build(context) {
return new MaterialApp(
home: PageStorage(
child: new MyHomePage(),
bucket: _bucket,
key: mykey,
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(context) {
return Center(
child: FloatingActionButton(
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => new NewPage()));
},
),
);
}
}
class NewPage extends StatefulWidget {
NewPageState createState() => NewPageState();
}
class NewPageState extends State<NewPage> {
String _text;
@override
void initState() {
super.initState();
updateText();
}
updateText() {
if (_bucket.readState(context, identifier: ValueKey(mykey)) != null) {
_text = _bucket.readState(context, identifier: ValueKey(mykey));
}
else {
print(_bucket.toString());
}
}
@override
Widget build(context) {
return PageStorage(
key:mykey,
bucket: _bucket,
child: Column(
children: <Widget>[
Text('The text is $_text'),
FloatingActionButton(
onPressed: () {
setState(() {
_bucket.writeState(context, 'Data saved',
identifier: ValueKey(mykey));
updateText();
});
},
)
],
),
);
}
}