Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 颤振:SharedReferences在应用程序启动时未获取值_Flutter - Fatal编程技术网

Flutter 颤振:SharedReferences在应用程序启动时未获取值

Flutter 颤振:SharedReferences在应用程序启动时未获取值,flutter,Flutter,我正在尝试存储一个值,并基于要导航到LandinPage或HomePage的值。但是,当我的应用程序加载时,我无法获取SharedReferences值。当前,该值是在单击登录页中的按钮时以及在我关闭/最小化应用程序时设置的。我甚至看不到main.dart的打印消息,也无法获取值。我做错了什么 这是我的密码: import 'package:credit/src/pages/landing.dart'; import 'package:flutter/material.dart'; import

我正在尝试存储一个值,并基于要导航到LandinPage或HomePage的值。但是,当我的应用程序加载时,我无法获取SharedReferences值。当前,该值是在单击登录页中的按钮时以及在我关闭/最小化应用程序时设置的。我甚至看不到main.dart的打印消息,也无法获取值。我做错了什么

这是我的密码:

import 'package:credit/src/pages/landing.dart';
import 'package:flutter/material.dart';
import 'package:credit/src/pages/credit/home.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    getUserStatus().then((userStatus) {
      if (userStatus == null) {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return LandingPage();
        }));
      } else {
        Navigator.of(context)
            .push(MaterialPageRoute<Null>(builder: (BuildContext context) {
          return HomePage();
        }));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

Future<String> getUserStatus() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String userStatus = prefs.getString('userstatus');
  print("==On Load Check ==");
  print(userStatus);
  return userStatus;
}

您已声明MyApp的main方法,但从未调用它。启动应用程序的主应用程序中包含runApp。您可以将prefs.getString移动到真正的main中,使其异步,然后将该值作为参数传递到MyApp小部件。

您已经声明了MyApp的方法main,但从未调用它。启动应用程序的主应用程序中包含runApp。您可以将prefs.getString移动到真正的main中,使其异步,然后将该值作为参数传递到MyApp小部件中。

您可能需要使用在两个页面中的任何一个之前首先加载的加载页面:

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'An App',
      home: LoadingPage(),
      routes: {
        '/landing': (context) => LandingPage(),
        '/home': (context) => HomePage(),
      }
    );
  }
}


class LoadingPage extends StatefulWidget {
  LoadingPage({Key key}) : super(key: key);

  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<LoadingPage> {
  @override
  void initState() {
    super.initState();
     loadPage();
  }

  loadPage() {
     getUserStatus().then((userStatus) {
      if (userStatus == null) {
        Navigator.of(context).pushNamed('/landing');
      } else {
        Navigator.of(context).pushNamed('/home');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('Home Page'),
    );
  }
}

class LandingPage extends StatefulWidget {
  LandingPage({Key key}) : super(key: key);

  _LandingPageState createState() => _LandingPageState();
}


class _LandingPageState extends State<LandingPage> {

  @override
  void initState() {
    super.initState();
    setUserStatus('done');
  }

  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('Landing'),
    );
  }
}

Future<String> getUserStatus() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String userStatus = prefs.getString('userStatus');
  print("==On Load Check ==");
  print(userStatus);
  return userStatus;
}

Future<bool> setUserStatus(String userStatus) async{
  SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.setString('userStatus', userStatus);
  return true;
}

您可能需要先使用加载页面,然后再加载两个页面中的任何一个:

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'An App',
      home: LoadingPage(),
      routes: {
        '/landing': (context) => LandingPage(),
        '/home': (context) => HomePage(),
      }
    );
  }
}


class LoadingPage extends StatefulWidget {
  LoadingPage({Key key}) : super(key: key);

  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<LoadingPage> {
  @override
  void initState() {
    super.initState();
     loadPage();
  }

  loadPage() {
     getUserStatus().then((userStatus) {
      if (userStatus == null) {
        Navigator.of(context).pushNamed('/landing');
      } else {
        Navigator.of(context).pushNamed('/home');
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Center(
      child: CircularProgressIndicator(),
    ));
  }
}

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('Home Page'),
    );
  }
}

class LandingPage extends StatefulWidget {
  LandingPage({Key key}) : super(key: key);

  _LandingPageState createState() => _LandingPageState();
}


class _LandingPageState extends State<LandingPage> {

  @override
  void initState() {
    super.initState();
    setUserStatus('done');
  }

  @override
  Widget build(BuildContext context) {
    return Container(
       child: Text('Landing'),
    );
  }
}

Future<String> getUserStatus() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String userStatus = prefs.getString('userStatus');
  print("==On Load Check ==");
  print(userStatus);
  return userStatus;
}

Future<bool> setUserStatus(String userStatus) async{
  SharedPreferences prefs = await SharedPreferences.getInstance();
  prefs.setString('userStatus', userStatus);
  return true;
}

我觉得威利的答案可能同样好,但这里有另一种方法

总的来说,我的方法是自动加载主主页,然后在主页的初始状态下,检查这是否是用户第一次访问应用程序。如果是这样,请立即将登录页弹出顶部。我成功地使用了这种方法,用户体验不好

下面是默认应用程序,但您的SharedReferences代码已移动到相应位置

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  var userStatus;

  //If user status is null, then show landing page.
  Future<void> checkUserStatus() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    userStatus = prefs.getString('userstatus');
    print("==On Load Check ==");
    print(userStatus);

    if (userStatus == null) {
      Navigator.push(context, MaterialPageRoute(builder: (context) => LandingPage()));
    }

  }


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

    //Call check for landing page in init state of your home page widget
    checkUserStatus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}


class LandingPage extends StatefulWidget {
  @override
  _LandingPageState createState() => _LandingPageState();
}

class _LandingPageState extends State<LandingPage> {
  @override
  Widget build(BuildContext context) {
    //Build landing page here.
    return Container();
  }
}

我觉得威利的答案可能同样好,但这里有另一种方法

总的来说,我的方法是自动加载主主页,然后在主页的初始状态下,检查这是否是用户第一次访问应用程序。如果是这样,请立即将登录页弹出顶部。我成功地使用了这种方法,用户体验不好

下面是默认应用程序,但您的SharedReferences代码已移动到相应位置

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  var userStatus;

  //If user status is null, then show landing page.
  Future<void> checkUserStatus() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    userStatus = prefs.getString('userstatus');
    print("==On Load Check ==");
    print(userStatus);

    if (userStatus == null) {
      Navigator.push(context, MaterialPageRoute(builder: (context) => LandingPage()));
    }

  }


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

    //Call check for landing page in init state of your home page widget
    checkUserStatus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(

        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}


class LandingPage extends StatefulWidget {
  @override
  _LandingPageState createState() => _LandingPageState();
}

class _LandingPageState extends State<LandingPage> {
  @override
  Widget build(BuildContext context) {
    //Build landing page here.
    return Container();
  }
}

谢谢你,埃里克,我也想过同样的方法,但是我想它会不会引起瞬间的闪烁?或者在重新定向到登录页之前浏览主页。不过我会尝试一下。谢谢你,埃里克,我也想过同样的方法,但我还是忍不住想,它会不会引起瞬间的闪烁?或者在重新定向到登录页之前浏览主页。我将尝试一下。我厌倦了使用相同的方法,但是,我得到了一个错误,它表示使用不包含导航器的上下文请求导航器操作。E/Flatter 8838:用于从导航器推送或弹出路由的上下文必须是导航器小部件的后代,我相信它没有获得正确的上下文,我已经更新了原始代码。知道为什么吗?我已经编辑了代码,使之成为一个完整的运行示例。只需复制、粘贴和编辑到您喜欢的位置。我通常使用命名路由,但你可以编辑它,看看它是否与路由生成器一起工作。@willienadi当我从登录页按后退按钮时,一个圆圈正在旋转,如何直接退出应用程序。但是,我厌倦了使用相同的方法,我得到一个错误,该错误表示请求的导航器操作的上下文不包括导航器。E/Flatter 8838:用于从导航器推送或弹出路由的上下文必须是导航器小部件的后代,我相信它没有获得正确的上下文,我已经更新了原始代码。知道为什么吗?我已经编辑了代码,使之成为一个完整的运行示例。只需复制、粘贴和编辑到您喜欢的位置。我通常使用命名路由,但您可以编辑它,并查看它是否与路由生成器一起工作。@willienadi当我从登录页按“后退”按钮时,一个圆圈正在旋转,如何直接退出应用程序。