Flutter 中的闪屏实现

Posted

技术标签:

【中文标题】Flutter 中的闪屏实现【英文标题】:Splash screen implementation in flutter 【发布时间】:2019-07-01 16:54:40 【问题描述】:

我是 Flutter 的新手,我想在我的应用程序中添加启动画面。我使用了 initState() 和导航器。但它没有用。应用程序打开时会出现闪屏,但之后它不会导航到下一个屏幕。

我的 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
        ),
      ),
    ),
  );


还有我的 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
               ),
            ),
          ),
        ),
      );
    
  

我该如何解决这个问题?

由于我是 Flutter 的新手,我不知道这是否是实现 splashScreen 的正确方法,如果还有其他更简单的方法,您也可以提出建议。

提前谢谢你。

【问题讨论】:

【参考方案1】:

代码更正:

MaterialApp 应该是所有 Widget 的父级(根)。

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
            ),
          ),
        ),
    );
  


【讨论】:

你可以使用pushReplacement,将push替换成@DarlanDieterich 注意:初始加载后会出现此启动画面。这意味着,启动应用程序时您可能仍会看到白屏。请参阅documentation 了解如何实现启动画面【参考方案2】:

默认提供启动画面实现。 您只需要更改相应平台中的代码,如下所示 对于安卓: 转到你的flutter项目中的android目录,在drawables下找到你将拥有launch_background.xml的res文件夹,只需替换你自己的启动图像,如下所示。 `

<?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>

对于 ios - 只需更改 ImageAssets 下的 LaunchImage。

【讨论】:

【参考方案3】:

您应该在退出初始屏幕时使用pushReplacement 而不是push,以防止它在您按下返回按钮时再次显示。

这是具有正确行为的 anmol.majhail 代码。

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
            ),
          ),
        ),
    );
  


【讨论】:

【参考方案4】:

要使用这个包:将依赖项添加到您的 pubspec.yaml 文件中。

dependencies:
    flutter:
        sdk: flutter
    splashscreen:

如何使用

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),
        ),
      ),
    );
  

【讨论】:

这就是我要找的!非常感谢,很容易实现【参考方案5】:

我在每个应用程序中使用的简单解决方案。

在构建方法代码sn-p中使用Timer

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
      ),
    );
  

【讨论】:

以上是关于Flutter 中的闪屏实现的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:快速创建简单闪屏页

flutter 打开应用的闪屏动画

如何在 Flutter 中移除原生闪屏和主屏幕之间的默认淡入淡出过渡? (仅使用本机启动画面)

Flutter入门篇- 如何实现登录动画效果

如何为闪屏生成清单文件?

Flutter 中的动态闪屏