颤振-页面之间的持久状态 [英] Flutter - Persistent State between Pages

查看:74
本文介绍了颤振-页面之间的持久状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在页面更改期间存储某些状态.因此,当重新加载页面时,旧的数据值可用.

I'm trying to store some state during page changes. So old data values are available when a page is reloaded.

我一直在研究PageStorage,但是还没有弄清楚它是如何工作的.

I've been looking into PageStorage but haven't figured out how it works yet.

我正在使用PageStorage.of(context)?.writeState(context, 'Some text is here', identifier: ValueKey('test'));写入存储,然后使用后退"按钮卸载页面.

I'm writing into the storage with PageStorage.of(context)?.writeState(context, 'Some text is here', identifier: ValueKey('test')); and then unloading the page with the back button.

当我重新加载页面(使用Navigator.of(context).push())时,使用PageStorage.of(context)?.readState(context, identifier: ValueKey('test'));只会使我为空;

When I reload the page (with Navigator.of(context).push()), using PageStorage.of(context)?.readState(context, identifier: ValueKey('test')); just gives me null;

这是我写的一个简短示例,以演示如何使用它.有人知道我在做什么错吗?

Here's a short sample that I wrote to demonstrate how I'm using it. Does anyone know what I'm doing wrong?

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'));
              });
            },
          )
        ],
      ),
    );
  }
}

推荐答案

您提供的代码存在多个问题.

There were multiple issues with the code you provided.

第一个在您的MyAppState中,您没有为PageStorage提供key.确实,没有密钥,书面数据就无法保存,我引用:

The first one being in your MyAppState where you didn't provided a key to your PageStorage. Indeed without the key , the written data cannot be saved and I quote :

writeState(BuildContext上下文,动态数据,{对象标识符})→无效 包:颤振

writeState(BuildContext context, dynamic data, {Object identifier}) → void package:flutter

使用指定的标识符或从给定的上下文计算出的标识符,将给定的数据写入此页面存储桶.计算出的标识符基于从上下文到拥有此页面存储桶的PageStorage小部件的路径中找到的PageStorageKeys.

Write the given data into this page storage bucket using the specified identifier or an identifier computed from the given context. The computed identifier is based on the PageStorageKeys found in the path from context to the PageStorage widget that owns this page storage bucket.

如果未提供显式标识符并且未找到 PageStorageKeys,则不会保存数据.

If an explicit identifier is not provided and no PageStorageKeys are found, then the data is not saved.

要解决此问题,只需创建一个全局变量PageStorageKey mykey = new PageStorageKey("testkey");并将其传递到创建PageStorage的地方:

To resolve this just create a global variable PageStorageKey mykey = new PageStorageKey("testkey"); and pass it along the creation of your 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,
      ),
    );
  }
}

然后再次使用相同的键来写入数据:

Then use the same key again to write the data :

onPressed: () {
              setState(() {
                PageStorage.of(context).writeState(context, 'Data saved',
                    identifier: ValueKey(mykey));
                updateText();
              });

最后,我认为更新文本不是最好的方法. 您应该创建一个方法(例如,updateText())并在写入数据后调用它.

Finally the way you update the text is, in my opinion not the best way to do it. You should create a method (updateText() for example) and call it after you wrote your data.

 updateText() {
    if (PageStorage.of(context) .readState(context, identifier: ValueKey(mykey)) != null) {
      _text = PageStorage .of(context).readState(context, identifier: ValueKey(mykey));
    } 
    else {
      _text = 'PageStorageNull';
    }
  }

和往常一样,检查该值是否为非null以避免错误是更安全的. 这是完整的代码:

As always it's safer to check if the value is non-null to avoid errors. Here is the full code :

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()方法中提供的数据更新文本.

With this code, press the button to go to the second page. On the second page press the button to update the text with the data provided in the writeState() method.

希望这可以为您提供帮助,

Hoping this can help you,

致谢

编辑

首先要拳头,对这一点的误解表示歉意.

Fist things first, sorry for misunderstanding the point.

实际上,您可以通过使用Bucket实现所需的功能. 实际上,PageStorage .of(context).readState(context, identifier: ValueKey(mykey));可以替换为:

And actually what you want is possible by using Buckets. Indeed the : PageStorage .of(context).readState(context, identifier: ValueKey(mykey)); can be replace by :

_bucket.readState(context, identifier: ValueKey(mykey));

因此,您要做的是将_bucket变量设置为全局变量,然后需要使用相同的Key NewPageState中的所有内容包装在PageStorageBucket作为您在MyAppState

So what you have to do is make your _bucket variable global, then you need to wrap everything you have in your NewPageState within a PageStorage using the same Key and Bucket as your first PageStorage in the MyAppState

这样做,您还可以使用存储桶进行读取,并通过导航保留数据.

Doing so you will be able to read using the bucket too and keep your data through navigation.

同样,他是完整的代码:

Again he is the full code:

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();
              });
            },
          )

        ],
      ),
    );
  }
}

这篇关于颤振-页面之间的持久状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆