【问题标题】:Check if an application is on its first run with Flutter检查应用程序是否首次使用 Flutter 运行
【发布时间】:2017-06-24 20:19:17
【问题描述】:

基本上,我希望在用户第一次打开应用程序时打开一个屏幕/视图。这将是一个登录屏幕类型的东西。

【问题讨论】:

标签: dart flutter


【解决方案1】:

使用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);
            }
        }
      },
    );

【讨论】:

  • 这行得通,但如果用户删除此应用程序的缓存怎么办。共享偏好也会被删除,对吧?
  • @NihadDelic 是的,它将被删除,但 SharedPreferences 是本地唯一可用的选项
  • 如果应用程序刚刚更新怎么办 - 我猜共享偏好仍然存在。那可能是个问题。我想我可以用保存的应用版本保存应用版本并决定。
  • 如果用户删除应用并重新安装会怎样
【解决方案2】:

上面的代码工作正常,但对于初学者我让它有点简单 ma​​in.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());
  }
}

然后分享偏好 MySharedPreferences

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 当用户第一次运行应用程序时,介绍屏幕只会出现一次,而无需删除应用程序或清除缓存 介绍屏幕

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()),
                            );
                          }
                        },
                      ),
                    )
                  ],
                ),
              ),
            ),
          )),
    );
  }
}

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多