提问人:Rafay Mushtaq 提问时间:12/8/2022 更新时间:12/9/2022 访问量:711
扑动。类型“Null”不是类型转换中类型“String”的子类型
Flutter. type 'Null' is not a subtype of type 'String' in type cast
问:
════════ 小部件库捕获的异常 ════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ 在构建 Builder 时抛出了以下_CastError: 类型“Null”不是类型转换中类型“String”的子类型
相关的导致错误的小部件是 MaterialApp在此处输入图片描述
我的代码已附上。这是关于麦克斯韦·乌迪米课程的。购买APP模块。当我在edit_product_screen中按下添加按钮时出现错误。他在 2019 年录制了这门课程。我面临此错误。我无法找出错误。任何人,请解决错误。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/product.dart';
import '../providers/products.dart';
class EditProductScreen extends StatefulWidget {
static const routeName = '/edit-product';
const EditProductScreen({super.key});
@override
State<EditProductScreen> createState() => _EditProductScreenState();
}
class _EditProductScreenState extends State<EditProductScreen> {
final priceFocus = FocusNode();
final imageControl = TextEditingController();
final form = GlobalKey<FormState>();
var isInit = true;
var initValues = {
'title': '',
'description': '',
'price': '',
'imageUrl': ''
};
var editProduct =
Product(id: '', title: '', desc: '', imageUrl: '', price: 0.0);
@override
void dispose() {
priceFocus.dispose();
imageControl.dispose();
super.dispose();
}
@override
void didChangeDependencies() {
if (isInit) {
final productid = ModalRoute.of(context)!.settings.arguments as String;
if (productid != null) {
editProduct =
Provider.of<Products>(context, listen: false).findById(productid);
initValues = {
'title': editProduct.title,
'description': editProduct.desc,
'price': editProduct.price.toString(),
'imageUrl': '',
};
imageControl.text = editProduct.imageUrl;
}
}
isInit = false;
super.didChangeDependencies();
}
void formSave() {
final valid = form.currentState!.validate();
if (!valid) {
return;
}
form.currentState!.save();
if (editProduct.id != null) {
Provider.of<Products>(context, listen: false)
.updateProduct(editProduct.id, editProduct);
} else {
Provider.of<Products>(context, listen: false).addProduct(editProduct);
}
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit Product'),
actions: [
IconButton(onPressed: formSave, icon: const Icon(Icons.save))
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: form,
child: ListView(
children: [
TextFormField(
initialValue: initValues['title'],
decoration: const InputDecoration(labelText: 'Title'),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(priceFocus);
},
onSaved: (newValue) {
editProduct = Product(
id: editProduct.id,
title: newValue as String,
desc: editProduct.desc,
imageUrl: editProduct.imageUrl,
price: editProduct.price,
isFavorite: editProduct.isFavorite,
);
},
validator: (value) {
if (value!.isEmpty) {
return 'Enter Title';
}
return null;
},
),
TextFormField(
initialValue: initValues['price'],
decoration: const InputDecoration(labelText: 'Price'),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
focusNode: priceFocus,
onSaved: (newValue) {
editProduct = Product(
id: editProduct.id,
title: editProduct.title,
desc: editProduct.desc,
imageUrl: editProduct.imageUrl,
price: double.parse(newValue as String),
isFavorite: editProduct.isFavorite,
);
},
),
TextFormField(
initialValue: initValues['description'],
decoration: const InputDecoration(labelText: 'Description'),
textInputAction: TextInputAction.next,
maxLines: 3,
keyboardType: TextInputType.multiline,
onSaved: (newValue) {
editProduct = Product(
id: editProduct.id,
title: editProduct.title,
desc: newValue as String,
imageUrl: editProduct.imageUrl,
price: editProduct.price,
isFavorite: editProduct.isFavorite,
);
},
),
Row(
children: [
Container(
height: 100,
width: 100,
margin: const EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey)),
child: imageControl.text.isEmpty
? const Center(child: Text('Enter Url'))
: FittedBox(
child: Image.network(
imageControl.text,
fit: BoxFit.cover,
),
),
),
Expanded(
child: TextFormField(
decoration:
const InputDecoration(labelText: 'Image Url'),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.url,
controller: imageControl,
onFieldSubmitted: (_) {
formSave();
},
onSaved: (newValue) {
editProduct = Product(
id: editProduct.id,
title: editProduct.title,
desc: editProduct.desc,
imageUrl: newValue as String,
price: editProduct.price,
isFavorite: editProduct.isFavorite,
);
},
),
),
],
),
],
)),
),
);
}
}
答:
0赞
IonicFireBaseApp
12/8/2022
#1
尝试检查这不应该为 nullModalRoute.of(context)!.settings.arguments
0赞
Guilherme Edington
12/8/2022
#2
在 didChangeDependencies 方法中,您正在实例化一个名为 productId 的变量,并从 ModalRoute.of(context).! 中获取一个值。settings.arguments 并转换为 String,但此值可以为 null,这就是为什么您在该行之后检查它是否为 null 的原因。
@override
void didChangeDependencies() {
if (isInit) {
final productid = ModalRoute.of(context)!.settings.arguments as String;
if (productid != null) {
editProduct =
Provider.of<Products>(context, listen: false).findById(productid);
initValues = {
'title': editProduct.title,
'description': editProduct.desc,
'price': editProduct.price.toString(),
'imageUrl': '',
};
imageControl.text = editProduct.imageUrl;
}
}
isInit = false;
super.didChangeDependencies();
}
所以你可以只转换为一个可为空的字符串,我认为你的问题已经解决了
final productid = ModalRoute.of(context)!.settings.arguments as String?;
评论