Было несколько проблем с кодом, который вы предоставили.
Первый находится в вашем MyAppState
, где вы не предоставили key
вашему PageStorage
. Действительно, без ключа записанные данные не могут быть сохранены, и я цитирую:
writeState (контекст BuildContext, динамические данные, {идентификатор объекта}) → void
пакет: флаттер
Запишите данные в эту корзину хранения страниц, используя указанный идентификатор или идентификатор, вычисленный из данного контекста. Вычисляемый идентификатор основан на значениях PageStorageKeys, найденных в пути от контекста к виджету PageStorage, которому принадлежит этот сегмент хранилища страниц.
Если явный идентификатор не указан и не найдены PageStorageKeys, данные не сохраняются.
Чтобы решить эту проблему, просто создайте глобальную переменную PageStorageKey mykey = new PageStorageKey("testkey");
и передайте ее для создания PageStorage
:
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();
});
},
)
],
),
);
}
}
С этим кодом нажмите кнопку, чтобы перейти на вторую страницу. На второй странице нажмите кнопку, чтобы обновить текст данными, предоставленными в методе writeState()
.
Надеясь, что это может вам помочь,
Привет
EDIT
Сначала нужно разобраться с вещами, извините за неправильное понимание сути.
А на самом деле то, что вы хотите, возможно с помощью Buckets.
Действительно: PageStorage .of(context).readState(context, identifier: ValueKey(mykey));
можно заменить на:
_bucket.readState(context, identifier: ValueKey(mykey));
Так что вам нужно сделать глобальную переменную _bucket
, тогда вам нужно обернуть все, что у вас есть в NewPageState
в PageStorage
, используя те же Key
и Bucket
как ваш первый PageStorage
в MyAppState
Таким образом, вы также сможете читать с помощью корзины и хранить данные в навигации.
Опять он полный код:
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();
});
},
)
],
),
);
}
}