需要一个“String”类型的值,但得到一个“Null”类型的值
Posted
技术标签:
【中文标题】需要一个“String”类型的值,但得到一个“Null”类型的值【英文标题】:Expected a value of type 'String', but got one of type 'Null' 【发布时间】:2021-09-18 03:31:46 【问题描述】:我必须在一个屏幕中添加新产品以及编辑现有产品。所以我使用了 didchangedependencies 方法,通过分配初始值来更新我的代码中出现问题的屏幕。请帮助我。所以错误是
此处显示错误:
@override
void didChangeDependencies()
if (_isinit)
final productId = ModalRoute.of(context)!.settings.arguments as String;
// ignore: unnecessary_null_comparison
if (productId != null)
_editedproduct =
Provider.of<Products>(context, listen: false).FindByID(productId);
_imageUrlController.text = _editedproduct.imageUrl;
_initValues =
'title': _editedproduct.title,
'description': _editedproduct.description,
'Price': _editedproduct.price.toString(),
// 'imageUrl': _editedproduct.imageUrl,
'imageUrl': '',
;
_isinit = false;
super.didChangeDependencies();
在更改依赖项方法中,我尝试从一页获取参数,即产品 ID,但它显示为空。 这是我已经推送到编辑屏幕产品页面的屏幕截图,其中包含我试图获取此参数的参数。 这是为了推动添加产品页面
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shoppingapp/Providers/Product.dart';
import 'package:shoppingapp/Providers/Products.dart';
class EditProductScreen extends StatefulWidget
static const routeName = '/edit-products';
@override
_EditProductScreenState createState() => _EditProductScreenState();
class _EditProductScreenState extends State<EditProductScreen>
final _priceFocusNode = FocusNode();
final _descriptionFocusNode = FocusNode();
final _imageUrlController = TextEditingController();
final _imageUrlFocusNode = FocusNode();
final _form = GlobalKey<FormState>();
var _editedproduct =
Product(id: '', title: '', description: '', price: 0, imageUrl: '');
var _isinit = true;
var _initValues =
'title': '',
'description': '',
'price': '',
'imageUrl': '',
;
@override
void initState()
_imageUrlFocusNode.addListener(_updateImageUrl);
super.initState();
@override
void didChangeDependencies()
if (_isinit)
final productId = ModalRoute.of(context)!.settings.arguments as String;
// ignore: unnecessary_null_comparison
if (productId != null)
_editedproduct =
Provider.of<Products>(context, listen: false).FindByID(productId);
_imageUrlController.text = _editedproduct.imageUrl;
_initValues =
'title': _editedproduct.title,
'description': _editedproduct.description,
'Price': _editedproduct.price.toString(),
// 'imageUrl': _editedproduct.imageUrl,
'imageUrl': '',
;
_isinit = false;
super.didChangeDependencies();
@override
void dispose()
_imageUrlFocusNode.removeListener(_updateImageUrl);
_priceFocusNode.dispose();
_descriptionFocusNode.dispose();
_imageUrlFocusNode.dispose();
super.dispose();
void _updateImageUrl()
if (!_imageUrlFocusNode.hasFocus)
setState(() );
void _saveForm()
final isValid = _form.currentState!.validate();
if (isValid)
return;
_form.currentState!.save();
if (_editedproduct.id != null)
Provider.of<Products>(context, listen: false)
.updateProducts(_editedproduct.id, _editedproduct);
else
Provider.of<Products>(context, listen: false).addProducts(_editedproduct);
Navigator.of(context).pop();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Edit Product'),
actions: [
IconButton(
icon: Icon(Icons.save),
onPressed: _saveForm,
),
],
),
body: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _form,
child: ListView(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'Title',
),
initialValue: _initValues['title'],
textInputAction: TextInputAction.next,
validator: (value)
if (value!.isEmpty)
return 'Please provide a value.';
return null;
,
onFieldSubmitted: (_)
FocusScope.of(context).requestFocus(_priceFocusNode);
,
onSaved: (value)
_editedproduct = Product(
title: value as String,
price: _editedproduct.price,
description: _editedproduct.description,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
,
),
TextFormField(
initialValue: _initValues['price'],
decoration: InputDecoration(
labelText: 'Price',
),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
focusNode: _priceFocusNode,
validator: (value)
if (value!.isEmpty)
return 'Please enter a price ';
if (double.tryParse(value) == null)
return 'Please Enter a Valid Number';
if (double.parse(value) <= 0)
return 'Please Enter the number greather no than zero';
,
onSaved: (value)
_editedproduct = Product(
title: _editedproduct.title,
price: double.parse(value!),
description: _editedproduct.description,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
,
),
TextFormField(
decoration: InputDecoration(
labelText: 'Description',
),
initialValue: _initValues['description'],
maxLines: 3,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.multiline,
focusNode: _descriptionFocusNode,
validator: (value)
if (value!.isEmpty)
return 'Please enter a description ';
if (value.length < 10)
return 'Should be at least 10 characters long.';
return null;
,
onSaved: (value)
_editedproduct = Product(
title: _editedproduct.title,
price: _editedproduct.price,
description: value as String,
imageUrl: _editedproduct.imageUrl,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
,
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey)),
child: _imageUrlController.text.isEmpty
? Text('Enter a URL')
: FittedBox(
child: Image.network(
_imageUrlController.text,
fit: BoxFit.cover,
),
),
),
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Image URl'),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imageUrlController,
focusNode: _imageUrlFocusNode,
validator: (value)
if (value!.isEmpty)
return 'Please enter a URL ';
if (!value.startsWith('http') &&
!value.startsWith('https'))
return 'Please Enter a valid URL';
if (!value.endsWith('.png') &&
!value.endsWith('.jpg') &&
!value.endsWith('.jpeg'))
return 'Please enter a valid image URL';
return null;
,
onFieldSubmitted: (_)
_saveForm();
,
onSaved: (value)
_editedproduct = Product(
title: _editedproduct.title,
price: _editedproduct.price,
description: _editedproduct.description,
imageUrl: value as String,
id: _editedproduct.id,
isFavourite: _editedproduct.isFavourite);
,
),
),
],
),
],
),
),
),
);
【问题讨论】:
究竟哪个变量为空,你知道吗? 我认为在 didchangedependencies 方法中,ProductID 变量 你已经添加了空检查 if (productId != null) ,现在你应该不会得到那个异常。 这是因为 _initvalues 中的 imageurl 吗? 我怀疑 _editedproduct 不提供所有值,使用 null 运算符升级颤振 【参考方案1】:虽然实现了 Null-Safety,但大多数教程都是在它之前制作的,因此在您尝试检查 ModalRoute
是否返回 null
值并根据该值执行操作的情况下,老 @ 987654323@ 现在无法使用。
相反,您可以这样做:
final productId = ModalRoute.of(context)!.settings.arguments == null ? "NULL":ModalRoute.of(context)!.settings.arguments as String;
if(productId != "NULL")
//Do stuff here
如果ModalRoute
为您提供null
,则将字符串“NULL”分配给变量productId
,否则您只需分配它返回的任何值。
然后您可以简单地检查productId
的值是否为NULL
并进行相应的操作。
【讨论】:
【参考方案2】:我想我回答这个问题迟了,但我的回答会在将来对某人有所帮助。
避免将参数转换为字符串。当 pushname 在没有任何参数的情况下被调用时会引发此错误,然后它会自动传递 null,当 null 强制转换为 String 时,就会发生错误。
像这行一样使用
final productId= ModalRoute.of(context)!.settings.arguments;
然后检查productId是否为空。如果不为空,则将产品对象转换为字符串
if (productId != null)
_editedProduct =
Provider.of<Products>(context, listen: false).findById(productId.toString());
......
【讨论】:
【参考方案3】:Jitesh Mohite (_editedProduct.id) 是 'build' 中的 null 变量,在 'didchangedependencies' 中它不是 null,它与 ProductId 的值相同
【讨论】:
这不回答问题,请在问题的cmets中提出您的问题。以上是关于需要一个“String”类型的值,但得到一个“Null”类型的值的主要内容,如果未能解决你的问题,请参考以下文章
需要一个“String”类型的值,但得到一个“Null”类型的值
如何修复 Flutter 需要一个“Map<String, dynamic>”类型的值,但得到一个“List<dynamic>”类型的值
需要一个“int”类型的值,但得到了 list<Map<string, dynamic>> 类型之一
错误:需要一个“String”类型的值,但在新的 note.Note.fromJson 中得到一个“Null”类型的值
需要一个“Widget”类型的值,但得到一个“Null”类型的值,颤动
Flutter 'showDatePicker' 抛出异常:错误:预期值为 'String' 类型,但得到类型为 'Null' 的值之一