Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if an application is on its first run with Flutter

Tags:

flutter

dart

Basically, I want to have a screen/view that will open when the user opens up the app for the first time. This will be a login screen type of thing.

like image 995
Alex Avatar asked Jun 24 '17 20:06

Alex


People also ask

How do I know if an app is running for the first time?

There's no reliable way to detect first run, as the shared preferences way is not always safe, the user can delete the shared preferences data from the settings! a better way is to use the answers here Is there a unique Android device ID? to get the device's unique ID and store it somewhere in your server, so whenever ...

How do I detect the platform my Flutter App is running on?

Last updated on January 10, 2022 Augustus Oop! Post a comment To detect the platform (or OS) your Flutter app is running on, just import dart:io and use the Platform class and its operatingSystem property (String). When running the following code, you’ll see something like the screenshot at the top of this article:

What is flutter and why should you learn it?

– With the growing number of supported build platforms, Flutter increases its value for developers who like to have only a single code base. Also, this creates the necessity to make design decisions based on the platform it’s running on because the underlying APIs to access the hardware can vary.

Is flutter a good choice for macOS?

MacOS? – With the growing number of supported build platforms, Flutter increases its value for developers who like to have only a single code base. Also, this creates the necessity to make design decisions based on the platform it’s running on because the underlying APIs to access the hardware can vary.

Can flutter provide an API that abstracts from two libraries?

Flutter provides two different APIs that enables the caller to get to know more about the current platform: the kIsWeb constant that is part of the foundation library and the Platform class being part of the platform library. The aim I have is to implement a class that provides an API that abstracts from these two quite low-level libraries.


2 Answers

Use Shared Preferences Package. You can read it with FutureBuilder, and you can check if there is a bool named welcome for example. This is the implementation I have in my code:

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);
            }
        }
      },
    );
like image 179
Abhi Agarwal Avatar answered Oct 22 '22 09:10

Abhi Agarwal


Above code work fine but for beginners I make it little bit simple 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());
  }
}

then share preferences 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;
  }
}

then create two dart files IntroScreen and Login Intro Screen will apear just once when user run application for first time usless the app is removed or caches are cleard 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),
        ],
      )
      ,
    );
  }
}

final step Login

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()),
                            );
                          }
                        },
                      ),
                    )
                  ],
                ),
              ),
            ),
          )),
    );
  }
}
like image 36
Naveed Abbas Avatar answered Oct 22 '22 09:10

Naveed Abbas