您如何处理向Flutter应用添加初始屏幕?它应该先加载并显示任何其他内容。当前,在加载Scaffold(home:X)小部件之前,会短暂闪烁一下颜色。
您如何处理向Flutter应用添加初始屏幕?它应该先加载并显示任何其他内容。当前,在加载Scaffold(home:X)小部件之前,会短暂闪烁一下颜色。
Answers:
我想在Flutter中更详细地介绍启动屏幕的实际方法。
我跟踪了一下这里的痕迹,发现Flutter中的“启动画面”看起来还不错。
也许大多数开发人员(像我一样)都认为Flutter默认没有Splash屏幕,因此他们需要为此做些事情。有一个启动画面,但背景为白色,没有人能理解默认情况下已经存在适用于iOS和Android的启动画面。
开发人员唯一需要做的就是将品牌形象放在正确的位置,初始屏幕将按此开始工作。
您可以按以下步骤进行操作:
首先在Android上使用(因为这是我最喜欢的平台:))
在Flutter项目中找到“ android”文件夹。
浏览至应用程序-> src->主菜单-> res文件夹,然后将品牌形象的所有变体放入相应的文件夹中。例如:
默认情况下,android文件夹中没有drawable-mdpi,drawable-hdpi等,但是我们可以根据需要创建它们。因此,需要将图像放置在mipmap文件夹中。另外,有关“启动画面”的默认XML代码(在Android中)将使用@mipmap,而不是@drawable资源(您可以根据需要进行更改)。
Android的最后一步是取消注释drawable / launch_background.xml文件中的某些XML代码。浏览到app-> src-> main-> res-> drawable,然后打开launch_background.xml。在此文件中,您将看到为什么Slash屏幕背景为白色。要应用我们在步骤2中放置的品牌形象,我们必须取消注释launch_background.xml文件中的某些XML代码。更改后,代码应如下所示:
<!--<item android:drawable="@android:color/white" />-->
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/your_image_name" />
</item>
请注意,我们注释了白色背景的XML代码,并且取消了有关mipmap图像的代码注释。如果有人感兴趣,可以在styles.xml文件中使用launch_background.xml文件。
在iOS上排名第二:
在Flutter项目中找到“ ios”文件夹。
浏览到Runner-> Assets.xcassets-> LaunchImage.imageset。应该有LaunchImage.png,LaunchImage @ 2x.png等。现在,您必须将这些图像替换为品牌图像变体。例如:
如果我没有记错的话,LaunchImage @ 4x.png默认情况下不存在,但是您可以轻松创建一个。如果LaunchImage@4x.png不存在,则还必须在Contents.json文件中声明它,该文件与图像位于同一目录中。更改后,我的Contents.json文件如下所示:
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@4x.png",
"scale" : "4x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
那应该是您所需要的,下次在Android或iOS上运行您的应用程序时,您应该拥有带有添加的品牌形象的正确的启动画面。
谢谢
Cannot resolve symbol '@mipmap/ic_launcher'
在Android Studio 3.1.1中出错(即使在重建缓存后也是如此),但是,该应用程序已编译并正常运行,并显示了启动器图形。
如果flutter create
您进行项目开发,则可以按照以下步骤进行操作:https://flutter.io/assets-and-images/#updating-the-launch-screen。
Flutter实际上为将启动画面添加到我们的应用程序提供了一种更简单的方法。我们在设计其他应用程序屏幕时首先需要设计一个基本页面。您需要将其设置为StatefulWidget,因为其状态将在几秒钟内发生变化。
import 'dart:async';
import 'package:flutter/material.dart';
import 'home.dart';
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
Timer(
Duration(seconds: 3),
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => HomeScreen())));
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Image.asset('assets/splash.png'),
),
);
}
}
逻辑 在initState()内,根据需要调用一个带有持续时间的Timer(),我将其设置为3秒钟,完成后将导航器推到应用程序的主屏幕。
注意:该应用程序应仅显示启动屏幕一次,用户不应在按后退按钮时再次回到启动屏幕。为此,我们使用Navigator.pushReplacement(),它将移动到新屏幕,并从导航历史记录堆栈中删除前一个屏幕。
为了更好地理解,请访问Flutter:设计自己的启动画面
目前还没有很好的例子,但是您可以使用每个平台的本机工具自行完成:
iOS:https://docs.nativescript.org/publishing/creating-launch-screens-ios
Android:https://www.bignerdranch.com/blog/splash-screens-the-right-way/
订阅问题8147,获取初始屏幕示例代码的更新。如果启动屏幕和iOS上的应用程序之间的黑色闪烁困扰您,请订阅问题8127进行更新。
编辑:自2017年8月31日起,新项目模板中现已提供对初始屏幕的改进支持。参见#11505。
对于Android,请转到android> app> src> main> res> drawable> launcher_background.xml
现在取消注释,并用您的图像位置替换@ mipmap / launch_image。
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item>
您可以在此处更改屏幕的颜色-
<item android:drawable="@android:color/white" />
最简单的在闪屏中添加启动画面的方法是在此程序包中添加以下内容:https : //pub.dev/packages/flutter_native_splash
将设置添加到项目的pubspec.yaml文件中,或使用设置在名为flutter_native_splash.yaml的根项目文件夹中创建一个文件。
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
图片必须是png文件。
您也可以在颜色中使用#。color:“#42a5f5”如果您不想为特定平台创建启动屏幕,也可以将android或ios设置为false。
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
android: false
如果图像应使用所有可用屏幕(宽度和高度),则可以使用fill属性。
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
fill: true
注意:iOS初始屏幕尚未实现fill属性。
如果要在Android上禁用全屏启动屏幕,则可以使用android_disable_fullscreen属性。
flutter_native_splash:
image: assets/images/splash.png
color: "42a5f5"
android_disable_fullscreen: true
添加设置后,使用
flutter pub pub run flutter_native_splash:create
程序包运行完毕后,您的初始屏幕已准备就绪。
您应该尝试以下代码,为我工作
import 'dart:async';
import 'package:attendance/components/appbar.dart';
import 'package:attendance/homepage.dart';
import 'package:flutter/material.dart';
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
void handleTimeout() {
Navigator.of(context).pushReplacement(new MaterialPageRoute(
builder: (BuildContext context) => new MyHomePage()));
}
startTimeout() async {
var duration = const Duration(seconds: 3);
return new Timer(duration, handleTimeout);
}
@override
void initState() {
// TODO: implement initState
super.initState();
_iconAnimationController = new AnimationController(
vsync: this, duration: new Duration(milliseconds: 2000));
_iconAnimation = new CurvedAnimation(
parent: _iconAnimationController, curve: Curves.easeIn);
_iconAnimation.addListener(() => this.setState(() {}));
_iconAnimationController.forward();
startTimeout();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Scaffold(
body: new Center(
child: new Image(
image: new AssetImage("images/logo.png"),
width: _iconAnimation.value * 100,
height: _iconAnimation.value * 100,
)),
),
);
}
}
@Collin Jackson和@Sniper都是正确的。您可以按照以下步骤分别在android和iOS中设置启动图像。然后在MyApp()的initState()中,可以使用Future.delayed设置计时器或调用任何api。在从Future返回响应之前,将显示您的启动图标,然后随着响应的出现,您可以移至初始屏幕之后要转到的屏幕。您可以看到此链接:Flutter Splash Screen
应用已验证的答案后出现未找到图像之类错误的人,请确保您添加的是@ mipmap / ic_launcher而不是@ mipmap / ic_launcher.png
如下所示添加页面并路由可能会有所帮助
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutkart/utils/flutkart.dart';
import 'package:flutkart/utils/my_navigator.dart';
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
// TODO: implement initState
super.initState();
Timer(Duration(seconds: 5), () => MyNavigator.goToIntro(context));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Colors.redAccent),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.white,
radius: 50.0,
child: Icon(
Icons.shopping_cart,
color: Colors.greenAccent,
size: 50.0,
),
),
Padding(
padding: EdgeInsets.only(top: 10.0),
),
Text(
Flutkart.name,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24.0),
)
],
),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Padding(
padding: EdgeInsets.only(top: 20.0),
),
Text(
Flutkart.store,
softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white),
)
],
),
)
],
)
],
),
);
}
}
如果您想继续进行下去,请访问:https : //www.youtube.com/watch?v=FNBuo-7zg2Q
您可以通过多种方式执行此操作,但是我使用的最简单的方式是:
对于启动图标,我使用Flutter库Flutter Launcher Icon
对于“自定义启动画面”,我创建了不同的屏幕分辨率,然后根据Android的分辨率将启动图像添加到mipmap文件夹中。
最后一部分是调整Android中res文件夹中drawable文件夹中的launch_background.xml。
只需将您的代码更改为如下所示:
<?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" />
<item android:drawable="@drawable/<splashfilename>" /> --> -->
<!-- You can insert your own image assets here -->
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/<Your splash image name here as per the mipmap folder>"/>
</item>
</layer-list>
我见过很少的开发人员将启动画面添加为可绘制画面,我尝试了此操作,但是以某种方式在Flutter 1.0.0和Dart SDK 2.0+中构建失败。因此,我更喜欢在位图部分添加启动画面。
iOS启动画面的创建相当简单。
在iOS的Runner文件夹中,只需使用与LaunchImage.png @ 2x,@ 3x,@ 4x同名的自定义启动画面图像更新LaunchImage.png文件即可。
只是增加一点,我觉得在LaunchImage.imageset中也有4x图像是一件好事。只需使用以下行更新Content.json中的代码(3倍以下)即可添加4倍比例选项:
{
"idiom" : "universal",
"filename" : "LaunchImage@4x.png",
"scale" : "4x"
}
使您的材料应用程序像这样
=>添加依赖
=> import导入'package:splashscreen / splashscreen.dart';
import 'package:flutter/material.dart';
import 'package:splashscreen/splashscreen.dart';
import 'package:tic_tac_toe/HomePage.dart';
void main(){
runApp(
MaterialApp(
darkTheme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: new MyApp(),
)
);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new SplashScreen(
seconds: 6,
navigateAfterSeconds: new HomePage(),
title: new Text('Welcome',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26.0,
color: Colors.purple,
),
),
image: Image.asset("images/pic9.png"),
backgroundColor: Colors.white,
photoSize: 150.0,
);
}
}
像这样的最终屏幕输出,您可以根据自己的要求更改秒数。
这是在Flutter中添加动态初始屏幕的无错误和最佳方法。
主飞镖
import 'package:flutter/material.dart';
import 'constant.dart';
void main() => runApp(MaterialApp(
title: 'GridView Demo',
home: SplashScreen(),
theme: ThemeData(
primarySwatch: Colors.red,
accentColor: Color(0xFF761322),
),
routes: <String, WidgetBuilder>{
SPLASH_SCREEN: (BuildContext context) => SplashScreen(),
HOME_SCREEN: (BuildContext context) => BasicTable(),
//GRID_ITEM_DETAILS_SCREEN: (BuildContext context) => GridItemDetails(),
},
));
闪屏
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:app_example/constants.dart';
class SplashScreen extends StatefulWidget {
@override
SplashScreenState createState() => new SplashScreenState();
}
class SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
var _visible = true;
AnimationController animationController;
Animation<double> animation;
startTime() async {
var _duration = new Duration(seconds: 3);
return new Timer(_duration, navigationPage);
}
void navigationPage() {
Navigator.of(context).pushReplacementNamed(HOME_SCREEN);
}
@override
dispose() {
animationController.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
animationController = new AnimationController(
vsync: this,
duration: new Duration(seconds: 2),
);
animation =
new CurvedAnimation(parent: animationController, curve: Curves.easeOut);
animation.addListener(() => this.setState(() {}));
animationController.forward();
setState(() {
_visible = !_visible;
});
startTime();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
new Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 30.0),
child: new Image.asset(
'assets/images/powered_by.png',
height: 25.0,
fit: BoxFit.scaleDown,
),
)
],
),
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Image.asset(
'assets/images/logo.png',
width: animation.value * 250,
height: animation.value * 250,
),
],
),
],
),
);
}
}
常量
String SPLASH_SCREEN='SPLASH_SCREEN';
String HOME_SCREEN='HOME_SCREEN';
HOMESCREEN.DART
import 'package:flutter/material.dart';
class BasicTable extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Table Widget")),
body: Center(child: Text("Table Widget")),
);
}
}
Jaldhi Bhatt的代码对我不起作用。
Flutter会在不包含导航器的上下文中引发' 导航器操作。”
我固定的代码包装该初始化使用路线导航上下文中的另一个部件的导航消费者组件内,如在所提到此文章。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:my-app/view/main-view.dart';
class SplashView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: Builder(
builder: (context) => new _SplashContent(),
),
routes: <String, WidgetBuilder>{
'/main': (BuildContext context) => new MainView()}
);
}
}
class _SplashContent extends StatefulWidget{
@override
_SplashContentState createState() => new _SplashContentState();
}
class _SplashContentState extends State<_SplashContent>
with SingleTickerProviderStateMixin {
var _iconAnimationController;
var _iconAnimation;
startTimeout() async {
var duration = const Duration(seconds: 3);
return new Timer(duration, handleTimeout);
}
void handleTimeout() {
Navigator.pushReplacementNamed(context, "/main");
}
@override
void initState() {
super.initState();
_iconAnimationController = new AnimationController(
vsync: this, duration: new Duration(milliseconds: 2000));
_iconAnimation = new CurvedAnimation(
parent: _iconAnimationController, curve: Curves.easeIn);
_iconAnimation.addListener(() => this.setState(() {}));
_iconAnimationController.forward();
startTimeout();
}
@override
Widget build(BuildContext context) {
return new Center(
child: new Image(
image: new AssetImage("images/logo.png"),
width: _iconAnimation.value * 100,
height: _iconAnimation.value * 100,
)
);
}
}
以下是在Flutter应用程序的IOS和Android平台中配置启动屏幕的步骤。
iOS平台
提交给Apple App Store的所有应用程序都必须使用Xcode故事板来提供应用程序的启动屏幕。让我们分三步进行:
步骤1:从您应用目录的根目录中打开ios / Runner.xcworkspace。
步骤2:从项目浏览器中选择Runner / Assets.xcassets,然后拖动所有尺寸(2x,3x等)的启动图像。您还可以从https://appicon.co/#image-sets生成不同大小的图像
步骤3:您可以看到LaunchScreen.storyboard文件正在显示提供的图像,在这里您还可以通过简单地拖动图像来更改图像的位置。有关更多信息,请参阅官方文档https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/launch-screen/
Android平台
在Android中,您的Android应用初始化时会显示启动屏幕。让我们以3个步骤设置此启动屏幕:-
步骤1:打开android / app / src / main / res / drawable / launch_background.xml文件。
步骤2:在第4行,您可以选择所需的颜色:-
<item android:drawable="@android:color/white" />
步骤3:在第10行,您可以更改图片:-
android:src="@mipmap/launch_image"
就是这样,您完成了!快乐编码:)
Flutter.dev已经为它提供了最佳答案,这既不是错误,也不是问题,只是配置。只需花一些时间阅读,一切都会解决。祝大家拥有美好的一天。
https://flutter.dev/docs/development/ui/advanced/splash-screen
SplashScreen(
seconds: 3,
navigateAfterSeconds: new MyApp(),
// title: new Text(
// 'Welcome In SplashScreen',
// style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
// ),
image: new Image.network('https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Tesla_Motors.svg/1200px-Tesla_Motors.svg.png'),
backgroundColor: Colors.white,
styleTextUnderTheLoader: new TextStyle(),
photoSize: 150.0,
loaderColor: Colors.black),
),
);