【问题标题】:Flutter: Access Stored Sharedpreference value from Other PagesFlutter:从其他页面访问存储的 Sharedpreference 值
【发布时间】:2018-12-15 08:07:14
【问题描述】:

我在名为page1.dart 的页面中存储了一个值。我想从page2.dart 或page3.dart 访问存储的值。我怎样才能做到这一点?

【问题讨论】:

  • 用什么刷屏
  • @RaoufRahiche 使用标签视图

标签: sharedpreferences flutter


【解决方案1】:

Flutter 共享首选项实际上是作为内存缓存实现的。第一次调用SharedPreferences.getInstance() 时,所有当前值都是从 NSUserDefaults(在 iOS 上)和 SharedPreferences(在 Android 上)读取并缓存在内存中。这涉及通道,异步也是如此。 Future 返回一个包装这个缓存的单例类。对 getInstance 的任何后续调用都会返回此单例类。

当您从共享首选项中获取值时,该值只是从内存缓存中获取。当您设置一个值时,缓存会立即更新,并且异步方法开始将其写回操作系统。 (您可以等待确认完成,但您不必这样做。)请注意,对缓存的读取和写入是同步的,因此您可以立即访问该设置缓存。 (到达操作系统可能需要一些时间,因此不能保证内存中的缓存与设备首选项匹配,但这应该只在错误条件下发生。)

这很有趣的原因是,一旦你得到SharedPreferences.getInstance() 的结果,你就可以同步读取和写入值。由于该实例是单例的,因此保留它的副本似乎是合理的。特别是,您可以使主异步并在那里获取它。

SharedPreferences sp;

void main() async {
  sp = await SharedPreferences.getInstance();
  runApp(new MyApp());
}

这允许您在整个代码中引用sp:

  onPressed: () {
    sp.setString('abc', 'def');
  },

知道内存中的缓存是一致的。特别是,在一个页面中设置的任何值都可以在导航后的另一个页面中获取。

说了这么多,您可能应该将存储的首选项视为状态的一部分,它恰好在启动时被初始化,并在设置时触发后台任务以自动保持它。然后,您可以按照与其他状态相同的方式处理首选项,但是您正在这样做(InheritedWidget + 控制器、Redux、Streams 等)。

【讨论】:

  • thnx 很多,但很高兴我不会再触及 sharedpreference 值,我只想存储用户名直到应用程序被卸载,我不会允许他更改值另一个页面,一旦我取得了结果,我会更新一个答案已解决的勾号,谢谢
  • 这个技巧帮助了我。在第 1 页设置首选项并转到第 2 页只是掩盖了问题。我想在 1 中设置一些东西并在 1 中看到它,这种更改使我的共享首选项可以在应用程序级别准备好,而不是依赖下面的答案。
  • 顺便说一句,这是一个很好的方法。它使您无需将 async 关键字添加到需要从 sharedPrefs 获取值的每个方法中。只需实例化一次,将其设为static,然后从代码中的任何位置调用它,无需等待。
  • 2020 年 10 月,这仍然是单身人士和在应用程序的不同部分访问的最佳答案
  • 这不会造成循环依赖吗?
【解决方案2】:

我在第一个屏幕中存储了一个字符串,然后通过以下代码从第二个屏幕中检索存储的值

第 1 页:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:trial/class2.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _email = '';

  @override
  void initState() {
    super.initState();
    _loadCounter();
  }

  _loadCounter() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _email = (prefs.getString('email') ?? '');
    });
  }

  _incrementCounter() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _email = "a@gmail.com";
    });
    prefs.setString('email', _email);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("title"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '$_email',
            ),
            new RaisedButton(
              child: new Text("next2"),
              onPressed: () {
                Navigator.push(context,
                    new MaterialPageRoute(builder: (context) => new Next()));
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        child: Icon(Icons.add),
      ),
    );
  }
}

第 2 页:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
String _email='';
class Next extends StatefulWidget {
  @override
  _NextState createState() => _NextState();
}

class _NextState extends State<Next> {
    @override
  void initState() {
    super.initState();
    _loadCounter();
  }

  _loadCounter() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _email = (prefs.getString('email')??'');
    });
  }
  @override
  Widget build(BuildContext context) {

    return Container(
      child: new Text("read value from sharepreference is:"+_email),
    );
  }
}

【讨论】:

    【解决方案3】:

    如果您需要在多个类中获取SharePreferences 的值,那么您可以将SharedPreference 的常用get 和set 方法放在一个类的静态方法中。

     import 'package:shared_preferences/shared_preferences.dart';
     class SharedPrefUtils {
    
        static saveStr(String key, String message) async {
           final SharedPreferences pref = await SharedPreferences.getInstance();
           pref.setString(key, message);
        }
    
        static readPrefStr(String key) async {
            final SharedPreferences pref = await SharedPreferences.getInstance();
            return pref.getString(key);
        }
    
     }
    

    然后,在任何其他类中,使用SharedPrefUtils.readPrefStr(String key);。

    【讨论】:

      【解决方案4】:

      在 Flutter 中使用 SharedPreferences 的最佳方法是将实例分配给一个全局变量,在你的 main 函数中初始化,使函数 async。

      一般来说,在 Flutter 中,main 函数仅用于设置到其他屏幕的路线并运行应用程序,因此如果您的起始路线是任何其他屏幕,那么当您到达该屏幕并需要使用 SharedPreferences 实例,它是可用的。

      真的不需要初始化函数。

      【讨论】:

        【解决方案5】:

        首先您需要为shared preferences 函数创建自定义类。所以你可以从任何页面访问它。

        import 'package:shared_preferences/shared_preferences.dart';
         
        class MySharedPreferences {
          MySharedPreferences._privateConstructor();
         
          static final MySharedPreferences instance =
              MySharedPreferences._privateConstructor();
         
          setStringValue(String key, String value) async {
            SharedPreferences myPrefs = await SharedPreferences.getInstance();
            myPrefs.setString(key, value);
          }
         
          Future<String> getStringValue(String key) async {
            SharedPreferences myPrefs = await SharedPreferences.getInstance();
            return myPrefs.getString(key) ?? "";
          }
         
          Future<bool> containsKey(String key) async {
            SharedPreferences myPrefs = await SharedPreferences.getInstance();
            return myPrefs.containsKey(key);
          }
         
          removeValue(String key) async {
            SharedPreferences myPrefs = await SharedPreferences.getInstance();
            return myPrefs.remove(key);
          }
         
          removeAll() async{
            SharedPreferences myPrefs = await SharedPreferences.getInstance();
            return myPrefs.clear();
          }
         
        }
        

        存储价值:

         MySharedPreferences.instance.setStringValue("key", value);
        

        获取价值:

        MySharedPreferences.instance
                .getStringValue("key")
                .then((value) => setState(() {
                      val result = value;
                    }));
        

        更多参考:Flutter Shared Preferences Tutorial

        【讨论】:

        • 这是一个很好的答案!两天以来,我一直在挠头来实施这样的事情。感谢您发布此内容。
        【解决方案6】:

        将共享首选项从主页面传递到您想要的所有页面。下面我以 Page1.dart 为例。可以使用相同的方法将参数传递给任何其他文件中的任何其他类。

        Page1.dart

        void main() async {
        
          // Note that this line is required, otherwise flutter throws an error 
          // about using binary messenger before runApp()
          WidgetsFlutterBinding.ensureInitialized();
        
          SharedPreferences sharedPref = await SharedPreferences.getInstance();
          runApp(new MyApp(sharedPref));
        }
        
        class MyApp extends StatelessWidget {
          final SharedPreferences sharedPref;
        
          MyApp(this.sharedPref);
        
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              home: MyHomePage(sharedPref),
            );
          }
        }
        
        class MyHomePage extends StatefulWidget {
          final SharedPreferences sharedPref;
        
          MyHomePage(this.sharedPref);
        
          @override
          _MyHomePageState createState() => _MyHomePageState();
        }
        
        class _MyHomePageState extends State<MyHomePage> {
          String _email = '';
        
          @override
          void initState() {
            super.initState();
            widget.sharedPref.setString('email', _email);
          }
        
          // ... rest of your code
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-02
          • 1970-01-01
          • 2013-12-22
          相关资源
          最近更新 更多