5
votes

I am new to Flutter and I wanted to have splash screen in my app. I used initState() and the navigator. But it didn't work. The app opens the splashscreen appears but after that it does not navigate to the next screen.

My main.dart

import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';

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

 class MyApp extends StatelessWidget{
 @override
 Widget build(BuildContext context) {
    return SplashScreen();
 }
}

class SplashScreen extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return SplashScreenState();
  }
}

class SplashScreenState extends State<SplashScreen>{
  @override
  void initState() {
    super.initState();
    Future.delayed(
      Duration(
        seconds: 4
      ),
      (){
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => HomePage(),
          )
        );
      }
  );
}
@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      backgroundColor: Colors.red,
      body: Text(
        'Welcome to BMI Calculator',
        style: new TextStyle(
          fontSize: 15.0,
          color: Colors.white,
          fontWeight: FontWeight.bold
        ),
      ),
    ),
  );
}
}

And my HomePage.dart

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget{
   @override
   Widget build(BuildContext context) {
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.red,
             title: Text(
              'BMI Calculator',
               style: new TextStyle(
                 color: Colors.white
               ),
            ),
          ),
        ),
      );
    }
  }

How can I resolve this?

Since I am new to flutter I dont know whether this is the right way to implement splashScreen if there are any other easier ways can you please suggest that also.

Thank you in advance.

5

5 Answers

12
votes

Code Corrected:

MaterialApp should be the parent(root) of all Widgets.

import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: SplashScreen()); // define it once at root level.
  }
}

class SplashScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return SplashScreenState();
  }
}

class SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(seconds: 4), () {
      Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => HomePage(),
          ));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.red,
      body: Text(
        'Welcome to BMI Calculator',
        style: new TextStyle(
            fontSize: 15.0, color: Colors.white, fontWeight: FontWeight.bold),
      ),
    );
  }
}

class HomePage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.red,
          title: Text(
            'BMI Calculator',
            style: new TextStyle(
                color: Colors.white
            ),
          ),
        ),
    );
  }

}
8
votes

The splash screen implementation is provided by default. You just need to change the code in respective platforms like below For Android: Go to android directory in your flutter project and find the res folder where you will have launch_background.xml under drawables , just replace your own splash image as below. `

<?xml version="1.0" encoding="utf-8"?>
    <!-- Modify this file to customize your launch splash screen -->
     <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@android:color/white" />
         <!-- You can insert your own image assets here -->
        <item>
         <bitmap
            android:gravity="center"
            android:src="@drawable/hotel_logo_new" />
    </item>
</layer-list>

For iOS - just change the LaunchImage under ImageAssets.

2
votes

You should use pushReplacement instead of push when you exit the splash screen to prevent it from showing again when you press the back button.

here's the anmol.majhail code with the correct behavior.

import 'package:flutter/material.dart';
import 'package:bmi/HomePage.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: SplashScreen()); // define it once at root level.
  }
}

class SplashScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return SplashScreenState();
  }
}

class SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(seconds: 4), () {
      Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) => HomePage(),
          ));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.red,
      body: Text(
        'Welcome to BMI Calculator',
        style: new TextStyle(
            fontSize: 15.0, color: Colors.white, fontWeight: FontWeight.bold),
      ),
    );
  }
}

class HomePage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.red,
          title: Text(
            'BMI Calculator',
            style: new TextStyle(
                color: Colors.white
            ),
          ),
        ),
    );
  }

}
1
votes

To use this package : add the dependency to your pubspec.yaml file.

dependencies:
    flutter:
        sdk: flutter
    splashscreen:

How to use

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SplashScreen(
        seconds: 10,
        imageBackground: AssetImage('assets/images/a.jpg'),
        navigateAfterSeconds: HomeScreen(),
      ),
    ); // define it once at root level.
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.red,
        title: Text(
          'Home',
          style: new TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}
0
votes

Simple solution which i use in every app.

Use Timer class in build method code snippet

class SplashScreen extends StatefulWidget {
  @override
  Splash createState() => Splash();
}

class Splash extends State<SplashScreen>  {

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

  }
  @override
  Widget build(BuildContext context) {
        Timer(
            Duration(seconds: 3),
                () =>
            Navigator.of(context).pushReplacement(MaterialPageRoute(
                builder: (BuildContext context) => LandingScreen())));


    var assetsImage = new AssetImage(
        'images/new_logo.png'); //<- Creates an object that fetches an image.
    var image = new Image(
        image: assetsImage,
        height:300); //<- Creates a widget that displays an image.

    return MaterialApp(
      home: Scaffold(
        /* appBar: AppBar(
          title: Text("MyApp"),
          backgroundColor:
              Colors.blue, //<- background color to combine with the picture :-)
        ),*/
        body: Container(
          decoration: new BoxDecoration(color: Colors.white),
          child: new Center(
            child: image,
          ),
        ), //<- place where the image appears
      ),
    );
  }
}