我只想在用户首次打开应用程序时显示入职屏幕,因此在“入职”屏幕的最后一页,我将“OnBoardingStatus”值设置为“Done”并移至主屏幕。但是,当用户下次打开应用程序时,此代码会将Onboarding屏幕刷新几毫秒,然后打开mainScreen。

这是我的代码


class App2 extends StatefulWidget {
  App2({Key key}) : super(key: key);
  @override
  _App2State createState() => _App2State();
}

class _App2State extends State<App2> {
  String onBoardingStatus;

  @override
  void initState() {
    // TODO: implement initState
    getOnBoardingStatus();
    super.initState();


  }

  Future<void> getOnBoardingStatus() async {
    WidgetsFlutterBinding.ensureInitialized();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var onboardingstatus = prefs.getString('OnBoardingStatus');
    setState(() {
      onBoardingStatus = onboardingstatus;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: onBoardingStatus != null
          ? MainScreen()
          : OnboardingScreen());
  }
}

最佳答案

当前,由于尚未检索onBoardingStatus实例,或者因为SharedPreferences确实为空,因此您无法知道OnBoardingStatus是否为null。您可以使用FutureBuilder解决此问题:

class App2 extends StatelessWidget {
  App2({Key key}) : super(key: key);

  Future<String> getOnBoardingStatus() async =>
    (await SharedPreferences.getInstance()).getString('OnBoardingStatus');

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getOnBoardingStatus(),
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          //TODO: Return a widget that indicates loading
        }
        return Scaffold(
            body: snapshot.data != null
                ? MainScreen()
                : OnboardingScreen());
      },
    );
  }
}

但是我认为这不是最好的解决方案。对于初学者,App2应该从外部来源获取状态-这样,如果您决定更改存储解决方案,则无需触摸App2

10-08 03:35