Flutter Web 在构建模式下显示空白屏幕
Flutter web shows a blank screen in build mode
在 flutter 上完成我的网络应用程序后,我尝试通过 flutter build web
命令在服务器上发布它。我将文件上传到服务器,但出现空白屏幕。
在 Android Studio 的调试模式下,它工作正常。
当我使用命令 flutter run -d chrome --profile --verbose
时,我也得到相同的空白屏幕我在这里发现了类似的问题,但根本原因似乎每次都不同,对我没有任何帮助,你能给我建议吗?
下面是我的 flutter 代码的简化版本,遇到同样的问题:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_signin_button/flutter_signin_button.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
//await Firebase.initializeApp();
ErrorWidget.builder = (FlutterErrorDetails details) {
bool inDebug = false;
assert(() { inDebug = true; return true; }());
// In debug mode, use the normal error widget which shows
// the error message:
if (inDebug)
return ErrorWidget(details.exception);
// In release builds, show a yellow-on-blue message instead:
return Container(
alignment: Alignment.center,
child: Text(
'Error! ${details.exception}',
style: TextStyle(color: Colors.yellow),
textDirection: TextDirection.ltr,
),
);
};
// Here we would normally runApp() the root widget, but to demonstrate
// the error handling we artificially fail:
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(), //fixing the scrolling for web
home:LoginScreen(),
theme: ThemeData(
cupertinoOverrideTheme: CupertinoThemeData( // <---------- this
textTheme: CupertinoTextThemeData(
pickerTextStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w900),
),
),
),
);
//
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
// etc.
};
}
class LoginScreen extends StatefulWidget {
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
late String em;
late String pa;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
body: buildHomeScreen()
),
);
}
Widget buildHomeScreen(){
return Container(
decoration: BoxDecoration(color: Colors.amberAccent),
child: Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Align(alignment: Alignment.centerLeft,
child: WelcomeText('Get to know the highest rated cars,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('good and bad things for each car,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('best car mechanics near you,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('best car agencies,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('and more..')),
SizedBox(height: 100,),
Text('Welcome to Car of your Dreams', style: GoogleFonts.ubuntu(
textStyle: TextStyle(fontSize: 35,
color: Colors.white,
fontWeight: FontWeight.w500,
decoration: TextDecoration.none))),
SizedBox(height: 8,),
Text('Sign in to continue', style: GoogleFonts.ubuntu(
textStyle: TextStyle(fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),
SizedBox(height: 12,),
FractionallySizedBox(
widthFactor: 0.6,
child: TextField(
onChanged: (value){
}
,
decoration: InputDecoration(
hintText: "Email",
border: OutlineInputBorder(),
icon:Icon(Icons.email),
contentPadding: EdgeInsets.symmetric(horizontal: 20),
),
),
),
SizedBox(height: 5,),
FractionallySizedBox(
widthFactor: 0.6,
child: TextField(
obscureText:true ,
onChanged: (value){
},
decoration: InputDecoration(
hintText: "Password",
border: OutlineInputBorder(),
icon:Icon(Icons.vpn_key_outlined),
contentPadding: EdgeInsets.symmetric(horizontal: 20),))
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(onPressed: () {},
child: Text('Sign in', style: GoogleFonts.londrinaSolid(
textStyle: TextStyle(fontSize: 25,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),),
SizedBox(width: 10,),
Icon(Icons.arrow_forward, color: Colors.white,)
],
),
SizedBox(height: 10,),
SignInButton(Buttons.Google,
text: "Sign in with Google",
onPressed:(){}),
SizedBox(height: 7,),
SignInButton(Buttons.Facebook,
text: "Sign in with Facebook",
onPressed: (){}),
SizedBox(height: 7,),
TextButton(
onPressed: (){
Navigator.pushNamed(context, '-1');
},
child: Text('New user? Register..', style: GoogleFonts.londrinaSolid(
textStyle: TextStyle(fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),),
SizedBox(height: 50,),
],
),
),
),
);
}
}
class WelcomeText extends StatelessWidget {
WelcomeText(this.welcomeText) ;
String welcomeText;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(20.0,0,0,0),
child: Text(welcomeText,
style: GoogleFonts.permanentMarker(
textStyle: TextStyle(fontSize: 30,
color: Colors.white70,
fontWeight: FontWeight.w100,
decoration: TextDecoration.none))),
);
}
}
编辑:我在 运行 调试模式下的代码之后添加了日志,请参见下文。我可以看到它运行但抱怨 Flexible 小部件,这可能是问题所在吗?
在 Chrome 上以调试模式启动 lib\main.dart...
正在等待来自 Chrome 调试服务的连接...
此应用程序链接到调试服务:ws://127.0.0.1:60918/FkBvyNxPDmI=/ws
侦听 ws://127.0.0.1:60918/FkBvyNxPDmI=/ws
的调试服务
运行声音空安全
侦听 ws://127.0.0.1:60918/FkBvyNxPDmI=/ws
的调试服务
======== widgets库捕获异常================================ =======================
应用父数据时抛出以下断言:
ParentDataWidget 使用不正确。
ParentDataWidget Flexible(flex: 1) 想要将 FlexParentData 类型的 ParentData 应用到已设置为接受不兼容类型 ParentData 的 ParentData 的 RenderObject。
通常,这意味着 Flexible 小部件具有错误的祖先 RenderObjectWidget。通常,Flexible 小部件直接放置在 Flex 小部件内。
有问题的 Flexible 当前放置在 DecoratedBox 小部件中。
接收到不兼容父数据的 RenderObject 的所有权链是:
RepaintBoundary ← NotificationListener ← NotificationListener ← _MaterialScrollbar ← Scrollbar ← Scrollable ← PrimaryScrollController ← SingleChildScrollView ← Flexible ← DecoratedBox ← ⋯
抛出异常时,这是堆栈:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart251:49throw
packages/flutter/src/widgets/framework.飞镖5753:11
packages/flutter/src/widgets/framework.dart 5768:14 [_updateParentData]
如果您看到空白的灰色屏幕,可能是您的代码中某处有空值,请检查您的值是否为空值
我通过更改 Flexible
小部件在小部件树中的位置来修复此问题,因此 buildHomeScreen
小部件现在变成如下:
Widget buildHomeScreen(){
return Container(
decoration: BoxDecoration(color: Colors.amberAccent),
child: Column(
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Align(alignment: Alignment.centerLeft,
child: WelcomeText('Get to know the highest rated cars,')),
在 flutter 上完成我的网络应用程序后,我尝试通过 flutter build web
命令在服务器上发布它。我将文件上传到服务器,但出现空白屏幕。
在 Android Studio 的调试模式下,它工作正常。
当我使用命令 flutter run -d chrome --profile --verbose
时,我也得到相同的空白屏幕我在这里发现了类似的问题,但根本原因似乎每次都不同,对我没有任何帮助,你能给我建议吗?
下面是我的 flutter 代码的简化版本,遇到同样的问题:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:flutter_signin_button/flutter_signin_button.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
//await Firebase.initializeApp();
ErrorWidget.builder = (FlutterErrorDetails details) {
bool inDebug = false;
assert(() { inDebug = true; return true; }());
// In debug mode, use the normal error widget which shows
// the error message:
if (inDebug)
return ErrorWidget(details.exception);
// In release builds, show a yellow-on-blue message instead:
return Container(
alignment: Alignment.center,
child: Text(
'Error! ${details.exception}',
style: TextStyle(color: Colors.yellow),
textDirection: TextDirection.ltr,
),
);
};
// Here we would normally runApp() the root widget, but to demonstrate
// the error handling we artificially fail:
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(), //fixing the scrolling for web
home:LoginScreen(),
theme: ThemeData(
cupertinoOverrideTheme: CupertinoThemeData( // <---------- this
textTheme: CupertinoTextThemeData(
pickerTextStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.w900),
),
),
),
);
//
}
}
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
// etc.
};
}
class LoginScreen extends StatefulWidget {
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
late String em;
late String pa;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
body: buildHomeScreen()
),
);
}
Widget buildHomeScreen(){
return Container(
decoration: BoxDecoration(color: Colors.amberAccent),
child: Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Align(alignment: Alignment.centerLeft,
child: WelcomeText('Get to know the highest rated cars,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('good and bad things for each car,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('best car mechanics near you,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('best car agencies,')),
Align(alignment: Alignment.centerLeft,child: WelcomeText('and more..')),
SizedBox(height: 100,),
Text('Welcome to Car of your Dreams', style: GoogleFonts.ubuntu(
textStyle: TextStyle(fontSize: 35,
color: Colors.white,
fontWeight: FontWeight.w500,
decoration: TextDecoration.none))),
SizedBox(height: 8,),
Text('Sign in to continue', style: GoogleFonts.ubuntu(
textStyle: TextStyle(fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),
SizedBox(height: 12,),
FractionallySizedBox(
widthFactor: 0.6,
child: TextField(
onChanged: (value){
}
,
decoration: InputDecoration(
hintText: "Email",
border: OutlineInputBorder(),
icon:Icon(Icons.email),
contentPadding: EdgeInsets.symmetric(horizontal: 20),
),
),
),
SizedBox(height: 5,),
FractionallySizedBox(
widthFactor: 0.6,
child: TextField(
obscureText:true ,
onChanged: (value){
},
decoration: InputDecoration(
hintText: "Password",
border: OutlineInputBorder(),
icon:Icon(Icons.vpn_key_outlined),
contentPadding: EdgeInsets.symmetric(horizontal: 20),))
),
SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(onPressed: () {},
child: Text('Sign in', style: GoogleFonts.londrinaSolid(
textStyle: TextStyle(fontSize: 25,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),),
SizedBox(width: 10,),
Icon(Icons.arrow_forward, color: Colors.white,)
],
),
SizedBox(height: 10,),
SignInButton(Buttons.Google,
text: "Sign in with Google",
onPressed:(){}),
SizedBox(height: 7,),
SignInButton(Buttons.Facebook,
text: "Sign in with Facebook",
onPressed: (){}),
SizedBox(height: 7,),
TextButton(
onPressed: (){
Navigator.pushNamed(context, '-1');
},
child: Text('New user? Register..', style: GoogleFonts.londrinaSolid(
textStyle: TextStyle(fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w300,
decoration: TextDecoration.none))),),
SizedBox(height: 50,),
],
),
),
),
);
}
}
class WelcomeText extends StatelessWidget {
WelcomeText(this.welcomeText) ;
String welcomeText;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(20.0,0,0,0),
child: Text(welcomeText,
style: GoogleFonts.permanentMarker(
textStyle: TextStyle(fontSize: 30,
color: Colors.white70,
fontWeight: FontWeight.w100,
decoration: TextDecoration.none))),
);
}
}
编辑:我在 运行 调试模式下的代码之后添加了日志,请参见下文。我可以看到它运行但抱怨 Flexible 小部件,这可能是问题所在吗? 在 Chrome 上以调试模式启动 lib\main.dart... 正在等待来自 Chrome 调试服务的连接... 此应用程序链接到调试服务:ws://127.0.0.1:60918/FkBvyNxPDmI=/ws 侦听 ws://127.0.0.1:60918/FkBvyNxPDmI=/ws
的调试服务运行声音空安全 侦听 ws://127.0.0.1:60918/FkBvyNxPDmI=/ws
的调试服务======== widgets库捕获异常================================ ======================= 应用父数据时抛出以下断言: ParentDataWidget 使用不正确。
ParentDataWidget Flexible(flex: 1) 想要将 FlexParentData 类型的 ParentData 应用到已设置为接受不兼容类型 ParentData 的 ParentData 的 RenderObject。
通常,这意味着 Flexible 小部件具有错误的祖先 RenderObjectWidget。通常,Flexible 小部件直接放置在 Flex 小部件内。 有问题的 Flexible 当前放置在 DecoratedBox 小部件中。
接收到不兼容父数据的 RenderObject 的所有权链是: RepaintBoundary ← NotificationListener ← NotificationListener ← _MaterialScrollbar ← Scrollbar ← Scrollable ← PrimaryScrollController ← SingleChildScrollView ← Flexible ← DecoratedBox ← ⋯ 抛出异常时,这是堆栈: C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart251:49throw packages/flutter/src/widgets/framework.飞镖5753:11 packages/flutter/src/widgets/framework.dart 5768:14 [_updateParentData]
如果您看到空白的灰色屏幕,可能是您的代码中某处有空值,请检查您的值是否为空值
我通过更改 Flexible
小部件在小部件树中的位置来修复此问题,因此 buildHomeScreen
小部件现在变成如下:
Widget buildHomeScreen(){
return Container(
decoration: BoxDecoration(color: Colors.amberAccent),
child: Column(
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Align(alignment: Alignment.centerLeft,
child: WelcomeText('Get to know the highest rated cars,')),