检查应用程序是否首次使用 Flutter 运行

Check if an application is on its first run with Flutter

基本上,我想要一个 screen/view 会在用户第一次打开应用程序时打开。这将是登录屏幕类型的东西。

使用Shared Preferences Package。你可以用 FutureBuilder 读取它,你可以检查是否有一个名为 welcome 的布尔值。这是我在代码中的实现:

return new FutureBuilder<SharedPreferences>(
      future: SharedPreferences.getInstance(),
      builder:
          (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return new LoadingScreen();
          default:
            if (!snapshot.hasError) {
              @ToDo("Return a welcome screen")
              return snapshot.data.getBool("welcome") != null
                  ? new MainView()
                  : new LoadingScreen();
            } else {
              return new ErrorScreen(error: snapshot.error);
            }
        }
      },
    );

上面的代码工作正常,但对于初学者我让它有点简单 main.dart

import 'package:flutter/material.dart';
import 'package:healthtic/IntroScreen.dart';
import 'package:healthtic/user_preferences.dart';
import 'login.dart';
import 'profile.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return MyAppState();
  }
}

class MyAppState extends State<MyApp> {
  // This widget is the root of your application.

  bool isLoggedIn = false;

  MyAppState() {
    MySharedPreferences.instance
        .getBooleanValue("isfirstRun")
        .then((value) => setState(() {
      isLoggedIn = value;
    }));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        //if true return intro screen for first time Else go to login Screen
        home: isLoggedIn ? Login() : IntroScreen());
  }
}

然后分享偏好 我的共享首选项

import 'package:shared_preferences/shared_preferences.dart';

class MySharedPreferences {
  MySharedPreferences._privateConstructor();

  static final MySharedPreferences instance =
  MySharedPreferences._privateConstructor();
  setBooleanValue(String key, bool value) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();
    myPrefs.setBool(key, value);
  }

  Future<bool> getBooleanValue(String key) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();
    return myPrefs.getBool(key) ?? false;
  }
}

然后创建两个 dart 文件 IntroScreenLogin 当用户 运行 首次使用应用程序时,除非删除应用程序或清除缓存,否则介绍屏幕将只出现一次 IntroScreen

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:healthtic/SliderModel.dart';
import 'package:healthtic/login.dart';
import 'package:healthtic/user_preferences.dart';
import 'package:shared_preferences/shared_preferences.dart';

class IntroScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Healthtic",
      home: IntorHome(),
      debugShowCheckedModeBanner: false,
    );
  }
}
class IntorHome extends StatefulWidget {
  @override
  _IntorHomeState createState() => _IntorHomeState();
}

class _IntorHomeState extends State<IntorHome> {
  List<SliderModel> slides=new List<SliderModel>();
  int currentIndex=0;

  PageController pageController=new PageController(initialPage: 0);


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    slides=getSlides();
  }

  Widget pageIndexIndicator(bool isCurrentPage) {
    return Container(
      margin: EdgeInsets.symmetric(horizontal: 2.0),
      height: isCurrentPage ? 10.0 : 6.0,
      width: isCurrentPage ? 10.0 :6.0,
      decoration: BoxDecoration(
          color: isCurrentPage ? Colors.grey : Colors.grey[300],
          borderRadius: BorderRadius.circular(12)
      ),
    );

  }
  @override
  Widget build(BuildContext context) {


    return Scaffold(

      body: PageView.builder(

          controller: pageController,
          onPageChanged: (val){
            setState(() {
              currentIndex=val;

            });
          },
          itemCount: slides.length,
          itemBuilder: (context,index){

            return SliderTile(


              ImageAssetPath: slides[index].getImageAssetPath(),
              title: slides[index].getTile(),
              desc: slides[index].getDesc(),


            );
          }),
      bottomSheet: currentIndex != slides.length-1 ? Container(
        height:  Platform.isIOS ? 70:60,
        padding: EdgeInsets.symmetric(horizontal: 20),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            GestureDetector(
                onTap: (){
                  pageController.animateToPage(slides.length-1, duration: Duration(
                    microseconds: 400,
                  ), curve: Curves.linear);
                },
                child: Text("Skip")
            ),
            Row(
              children: <Widget>[
                for(int i=0;i<slides.length;i++) currentIndex == i ?pageIndexIndicator(true): pageIndexIndicator(false)
              ],
            ),
            GestureDetector(
                onTap: (){
                  pageController.animateToPage(currentIndex+1, duration: Duration(
                      microseconds: 400
                  ), curve: Curves.linear);
                },
                child: Text("Next")
            ),
          ],
        ),
      ) : Container(
        alignment: Alignment.center,
        width: MediaQuery.of(context).size.width,
        height: Platform.isIOS ? 70:60,
        color: Colors.blue,
        child:
        RaisedButton(
          child: Text("Get Started Now",style: TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.w300
          ),
          ),
          onPressed: (){
            MySharedPreferences.instance
                .setBooleanValue("isfirstRun", true);

            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (_) => Login()),
            );
          },
        ),

      ),
    );
  }
}
class SliderTile extends StatelessWidget {
  String ImageAssetPath, title, desc;

  SliderTile({this.ImageAssetPath, this.title, this.desc});

  @override
  Widget build(BuildContext context) {
    return Container(

      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,

        children: <Widget>[

          Image.asset(ImageAssetPath),
          SizedBox(height: 20,),
          Text(title),
          SizedBox(height: 12,),
          Text(desc),
        ],
      )
      ,
    );
  }
}

最后一步登录

import 'package:flutter/material.dart';
import 'package:healthtic/user_preferences.dart';
import 'profile.dart';

class Login extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return LoginState();
  }
}

class LoginState extends State<Login> {
  TextEditingController controllerEmail = new TextEditingController();
  TextEditingController controllerUserName = new TextEditingController();
  TextEditingController controllerPassword = new TextEditingController();

  @override
  Widget build(BuildContext context) {

    final formKey = GlobalKey<FormState>();

    // TODO: implement build
    return SafeArea(
      child: Scaffold(
          body: SingleChildScrollView(
            child: Container(
              margin: EdgeInsets.all(25),
              child: Form(
                key: formKey,
                autovalidate: false,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Text("Email Id:", style: TextStyle(fontSize: 18)),
                        SizedBox(width: 20),
                        Expanded(
                          child: TextFormField(
                            controller: controllerEmail,
                            decoration: InputDecoration(
                              hintText: "Please enter email",
                            ),
                            keyboardType: TextInputType.emailAddress,
                            validator: (value) {
                              if (value.trim().isEmpty) {
                                return "Email Id is Required";
                              }
                            },
                          ),
                        )
                      ],
                    ),
                    SizedBox(height: 60),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Text("UserName:", style: TextStyle(fontSize: 18)),
                        SizedBox(width: 20),
                        Expanded(
                          child: TextFormField(
                              decoration: InputDecoration(
                                hintText: "Please enter username",
                              ),
                              validator: (value) {
                                if (value.trim().isEmpty) {
                                  return "UserName is Required";
                                }
                              },
                              controller: controllerUserName),
                        )
                      ],
                    ),
                    SizedBox(height: 60),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Text("Password:", style: TextStyle(fontSize: 18)),
                        SizedBox(width: 20),
                        Expanded(
                          child: TextFormField(
                              decoration: InputDecoration(
                                hintText: "Please enter password",
                              ),
                              obscureText: true,
                              validator: (value) {
                                if (value.trim().isEmpty) {
                                  return "Password is Required";
                                }
                              },
                              controller: controllerPassword),
                        )
                      ],
                    ),
                    SizedBox(height: 100),
                    SizedBox(
                      width: 150,
                      height: 50,
                      child: RaisedButton(
                        color: Colors.grey,
                        child: Text("Submit",
                            style: TextStyle(color: Colors.white, fontSize: 18)),
                        onPressed: () {
                          if(formKey.currentState.validate()) {
                            var getEmail = controllerEmail.text;
                            var getUserName = controllerUserName.text;
                            var getPassword = controllerPassword.text;
                            
                            MySharedPreferences.instance
                                .setBooleanValue("loggedin", true);

                            Navigator.pushReplacement(
                              context,
                              MaterialPageRoute(builder: (_) => Profile()),
                            );
                          }
                        },
                      ),
                    )
                  ],
                ),
              ),
            ),
          )),
    );
  }
}