意外的空值 Flutter
unexpected null value Flutter
大家好,我是 dart 和 flutter 的新手
当我 运行 项目遇到一个错误 说意外的空值时,我找不到错误在哪里,我认为问题出在 Null Safety 中。
我有三个 classes 其中两个用于屏幕,一个用于模型,
import 'package:enpc_site/screens/body_page.dart';
import 'package:enpc_site/screens/navigate_bar.dart';
import 'package:enpc_site/screens/our_services.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(150),
child: AppBar(
backgroundColor: Colors.black,
flexibleSpace: NavigateBar(),
),
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 0, 0, 0),
Color.fromARGB(255, 49, 8, 8)
])),
height: double.infinity,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 100),
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 200),
child: WhoWe(),
),
Padding(
padding: const EdgeInsets.only(top: 200),
child: OurServices(), // here i'm calling my second screen class
)
],
),
)),
),
);
}
}
第二个class
import 'package:enpc_site/models/products.dart';
import 'package:flutter/material.dart';
class OurServices extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraint) {
return BodyPage();
},
);
}
}
class BodyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Products? product;
String image = product!.products[0].image;
String name = product.products[0].name;
String desc = product.products[0].discription;
return Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"SERVICES",
style: TextStyle(fontSize: 25, color: Colors.white),
),
SizedBox(
height: 20,
),
Text(
"CE QUE NOUS PRODUISON",
style: TextStyle(
fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white),
),
SizedBox(
height: 40,
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('$image' , width: 400, height: 300,),
Text(
'$name',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: '$desc',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(
width: 20,
),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/port.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(
width: 20,
),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/Sheet.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(width: 20,),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/gainePlastic.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
],
),
)
],
),
);
}
}
这是型号 class 产品
class Products {
final String name, discription;
final String image;
Products(
{ required this.name, required this.discription, required this.image});
List<Products> products = [
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/port.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/Sheet.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
];
}
您没有初始化第二个 class,您没有初始化 'product' 变量来访问模型 class 中的列表。它确实设置为空。要解决此问题,首先创建模型 class 'Products' 的实例,然后使用该实例变量访问 class 中的列表。将该列表分配给一个变量并在您的 UI 中使用它。
此外,建议您在 'build' 方法之外声明变量,因为每次需要刷新 UI 时构建方法都会运行,这可能会重置您的值。这可能不是所需的行为,但这取决于应用程序。
要访问 class 中的列表,您首先需要像这样创建 class 的实例:
final Products instanceOfProductsClass = Products(name: 'name', discription: 'discription', image: 'image');
//now using this inscance, access the list.
final list = instanceOfProductsClass.products;
String image = list[0].image;
String name = list[0].name;
String desc = list[0].discription;
这将解决您的空错误,但会导致另一个错误。您构建 class 的方式是错误的。这就是为什么。在您的 class 中,您正在创建类型 'Products' 的列表,其中有 5 个相同 class 的实例。现在,列表中此 class 的每个实例也将尝试创建相同的列表,并且这些实例也将尝试执行相同的操作,并且这种情况会一直发生,直到最终出现堆栈溢出错误。
为避免这种情况,您不应在 class 本身中创建产品列表,而应在您计划使用它的小部件中或在您管理应用程序数据的单独文件中创建,例如所以:
class Product {
final String name, discription;
final String image;
//List has been removed from the class itself
Product({
required this.name,
required this.discription,
required this.image,
});
}
现在在您的小部件中创建您的产品列表,如下所示:
class BodyPage extends StatelessWidget {
final List<Product> products = [
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/port.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/Sheet.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
];
@override
Widget build(BuildContext context) {
String image = products[0].image;
String name = products[0].name;
String desc = products[0].discription;
return Container(....
这里有些东西很奇怪。
如果您仔细观察,您会发现产品列表在产品 class 中。
将所有产品存储在单个产品 class 中没有意义。
这会导致问题,因为在 BodyPage 中,您在构建函数中引用了一个空的 Products 对象。您可以通过从产品 class 中提取产品列表来修复它,然后像这样将其导入产品主体:
product.dart
class Products {
final String name, discription;
final String image;
Products({
required this.name,
required this.discription,
required this.image,
});
}
List<Products> products = [
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/port.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/Sheet.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
];
BodyPage(在构建方法中 - 不要忘记导入产品):
class BodyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String image = products[0].image;
String name = products[0].name;
String desc = products[0].discription;
...
}
...
}
大家好,我是 dart 和 flutter 的新手
当我 运行 项目遇到一个错误
import 'package:enpc_site/screens/body_page.dart';
import 'package:enpc_site/screens/navigate_bar.dart';
import 'package:enpc_site/screens/our_services.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(150),
child: AppBar(
backgroundColor: Colors.black,
flexibleSpace: NavigateBar(),
),
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromARGB(255, 0, 0, 0),
Color.fromARGB(255, 49, 8, 8)
])),
height: double.infinity,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 100),
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 200),
child: WhoWe(),
),
Padding(
padding: const EdgeInsets.only(top: 200),
child: OurServices(), // here i'm calling my second screen class
)
],
),
)),
),
);
}
}
第二个class
import 'package:enpc_site/models/products.dart';
import 'package:flutter/material.dart';
class OurServices extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraint) {
return BodyPage();
},
);
}
}
class BodyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Products? product;
String image = product!.products[0].image;
String name = product.products[0].name;
String desc = product.products[0].discription;
return Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"SERVICES",
style: TextStyle(fontSize: 25, color: Colors.white),
),
SizedBox(
height: 20,
),
Text(
"CE QUE NOUS PRODUISON",
style: TextStyle(
fontSize: 40, fontWeight: FontWeight.bold, color: Colors.white),
),
SizedBox(
height: 40,
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('$image' , width: 400, height: 300,),
Text(
'$name',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: '$desc',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(
width: 20,
),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/port.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(
width: 20,
),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/Sheet.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
SizedBox(width: 20,),
Container(
height: 500,
width: 500,
decoration: BoxDecoration(
color: Color.fromARGB(100, 240, 240, 240),
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('assets/images/gainePlastic.png', width: 400, height: 300,),
Text(
'Gaine Plastic',
style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
),
RichText(
text: TextSpan(text: 'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension',
style: TextStyle(color: Colors.white, fontSize: 15), ),
),
],
),
),
),
],
),
)
],
),
);
}
}
这是型号 class 产品
class Products {
final String name, discription;
final String image;
Products(
{ required this.name, required this.discription, required this.image});
List<Products> products = [
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/port.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/Sheet.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
];
}
您没有初始化第二个 class,您没有初始化 'product' 变量来访问模型 class 中的列表。它确实设置为空。要解决此问题,首先创建模型 class 'Products' 的实例,然后使用该实例变量访问 class 中的列表。将该列表分配给一个变量并在您的 UI 中使用它。 此外,建议您在 'build' 方法之外声明变量,因为每次需要刷新 UI 时构建方法都会运行,这可能会重置您的值。这可能不是所需的行为,但这取决于应用程序。
要访问 class 中的列表,您首先需要像这样创建 class 的实例:
final Products instanceOfProductsClass = Products(name: 'name', discription: 'discription', image: 'image');
//now using this inscance, access the list.
final list = instanceOfProductsClass.products;
String image = list[0].image;
String name = list[0].name;
String desc = list[0].discription;
这将解决您的空错误,但会导致另一个错误。您构建 class 的方式是错误的。这就是为什么。在您的 class 中,您正在创建类型 'Products' 的列表,其中有 5 个相同 class 的实例。现在,列表中此 class 的每个实例也将尝试创建相同的列表,并且这些实例也将尝试执行相同的操作,并且这种情况会一直发生,直到最终出现堆栈溢出错误。
为避免这种情况,您不应在 class 本身中创建产品列表,而应在您计划使用它的小部件中或在您管理应用程序数据的单独文件中创建,例如所以:
class Product {
final String name, discription;
final String image;
//List has been removed from the class itself
Product({
required this.name,
required this.discription,
required this.image,
});
}
现在在您的小部件中创建您的产品列表,如下所示:
class BodyPage extends StatelessWidget {
final List<Product> products = [
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/port.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/Sheet.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
Product(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat
dépendent de la norme NF C 15-100 relative aux installations électriques à
basse tension ',
image: 'assets/images/gainePlastic.png'),
];
@override
Widget build(BuildContext context) {
String image = products[0].image;
String name = products[0].name;
String desc = products[0].discription;
return Container(....
这里有些东西很奇怪。 如果您仔细观察,您会发现产品列表在产品 class 中。 将所有产品存储在单个产品 class 中没有意义。 这会导致问题,因为在 BodyPage 中,您在构建函数中引用了一个空的 Products 对象。您可以通过从产品 class 中提取产品列表来修复它,然后像这样将其导入产品主体:
product.dart
class Products {
final String name, discription;
final String image;
Products({
required this.name,
required this.discription,
required this.image,
});
}
List<Products> products = [
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/port.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/Sheet.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
Products(
name: 'Gaine Plastic',
discription:
'Les gaines ou fourreaux de protection utilisables dans l\'habitat dépendent de la norme NF C 15-100 relative aux installations électriques à basse tension ',
image: 'assets/images/gainePlastic.png'),
];
BodyPage(在构建方法中 - 不要忘记导入产品):
class BodyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String image = products[0].image;
String name = products[0].name;
String desc = products[0].discription;
...
}
...
}