【问题标题】:Problem implementing shared_preferrences in flutter在颤振中实现 shared_preferences 的问题
【发布时间】:2020-06-03 21:59:25
【问题描述】:

以下代码是我的登录屏幕的一部分。我正在使用 shared_preferences 来保存记住我复选框和用户名。复选框值有效,但未设置用户名。我知道它正在被保存,因为我可以使用 print 查看该值。但我想它设置得太晚了,因为我的 TextField 是空白的。有什么想法吗?

class RmoLogin extends StatefulWidget {
  static const String id = 'login_screen';

  @override
  _RmoLoginState createState() => _RmoLoginState();
}

class _RmoLoginState extends State<RmoLogin> {
  final TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);

  final TextEditingController usernameController = TextEditingController(); 

  final TextEditingController passwordController = TextEditingController(); 

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  bool showSpinner = false;
  bool rememberMe = false;
  String userName = '';

  _saveRememberUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString('username', usernameController.text);
    prefs.setBool('remember', rememberMe);
  }

  _getRememberUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    userName = prefs.getString('username') ?? '';
    rememberMe = prefs.getBool('remember') ?? false;
  }

  @override
  void initState() {
    super.initState();
    _getRememberUser();
    if (rememberMe) {
      usernameController.text = userName;
    }
  }

  @override
  Widget build(BuildContext context) {
    final userField = UserTextField(style: style, usernameController: usernameController);

    final passwordField = PasswordTextField(style: style, passwordController: passwordController);

    final rememberMeCheckbox = Checkbox(
      value: rememberMe,
      onChanged: (newValue) {
        setState(() {
          rememberMe = newValue;
        });
      },
    );

【问题讨论】:

  • 它返回一个Future,你可以使用await。例如await prefs.setString('username', usernameController.text);

标签: flutter


【解决方案1】:

因为 SharedPreferences 实例化是异步的,而构建方法本身不是,所以在创建实例并访问值时,构建方法已经被调用并构建了您的小部件。

但是,对于 SharedPreferences 和数据库之类的东西,实现它们的最佳方式是使用 Singleton 方法,即,您可以在整个应用程序中使用一个实例。 在这种情况下,不要在调用任一方法时创建新的 SharedPreferences 实例,最好创建它的单个实例并使用该实例来更新集合并获取值。

您还可以为 SharedPreferences 创建一个服务,您可以在整个应用程序中使用它。

  class SharedPreferencesService {
    final SharedPreferences _prefs;

    SharedPreferencesService(this._prefs);

    // define methods here
  }

然后在您的 main 方法中,您可以创建一个 SharedPreferences 实例并使用它来初始化 SharedPreferencesService。

例如。


 SharedPreferencesService service; 

 Future<void> main() async {
   // flutter will complain if this isn't present
   WidgetsFlutterBinding.ensureInitialized();

   final prefs = await SharedPreferences.getInstance();
   service = SharedPreferencesService(prefs);
   runApp(YourApp());
 }

然后你想在你的应用程序中使用它的任何地方,你都可以调用服务上的方法名称。最好对 SharedPreferencesService 使用依赖注入,你可以试试get_it 库。

【讨论】:

【解决方案2】:

简单看一下....但是

initState() 是异步方法时,您在 initState() 内同步调用 _getRememberUser

initState() 不是调用它的正确位置,因为initState() 本身就是一个同步@override。

我的解决方案是在您的build() 方法中使用FutureBuilder,并在那里调用_getRememberUser

【讨论】:

    【解决方案3】:

    您只需要更新状态,检查以下解决方案:

    bool rememberMe = false;
    String userName = '';
    
    @override
      void initState() {
        // TODO: implement initState
        super.initState();
        _getRememberUser();
      }
    
        _getRememberUser() async {
            SharedPreferences prefs = await SharedPreferences.getInstance();
            setState(() {
              userName = prefs.getString('username') ?? '';
              rememberMe = prefs.getBool('remember')?? false;
            });
            if (rememberMe) {
              usernameController.text = userName;
            }
            print(userName +'-->'+rememberMe.toString());
          }
    

    编码愉快!!

    【讨论】:

      猜你喜欢
      • 2019-06-08
      • 2019-12-20
      • 2021-11-26
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      相关资源
      最近更新 更多