【发布时间】:2021-10-27 11:16:18
【问题描述】:
我正在编写一个管理员将图像上传到 Firebase 的代码。当我将 if else 语句添加到两个函数时出现错误 该图像,您可以在该图像中写下该产品的描述。但是在从移动相机或图库中捕获图像后,错误会以红屏显示空检查值。我认为这是 由于 bang 运算符,但我发现很难在 if(?) else(:) 语句中创建一个替代语句来运行两个函数。
执行以下 if else 语句后显示以下错误
当我单击控制台中的错误行之一时,它会将我带到以下位置
颤振医生
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19041.1165], locale en-PK)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio
[√] Connected device (3 available)
• No issues found!
下面是错误线指向 bang(!) 运算符的函数
pickPhotoFromGallery()async {
final imagefile= await ImagePicker().pickImage(source: ImageSource.gallery);
final _imageselected=File(imagefile!.path);
setState(() {
this.file=_imageselected;
});
}
displayAdminiUploadFormScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(icon: Icon(Icons.arrow_back,color: Colors.white,),
onPressed: clearFormInfo(),
),
title: Text('New Product',style: TextStyle(color: Colors.white,fontSize: 24.0,fontWeight: FontWeight.bold),),
actions: [
FlatButton(onPressed: (){
uploading ? null: uploadImageandSaveItem();
},
child: Text('Add',style: TextStyle(color: Colors.pink,fontSize: 16.0,fontWeight: FontWeight.bold),)
),
],
),
body: ListView(
children: [
uploading ? circularProgress():Text(''),
Container(
height: 230.0,
width: MediaQuery.of(context).size.width*0.8,
child: Center(
child: AspectRatio
(aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(image:DecorationImage(image:FileImage(file!),fit:BoxFit.cover)),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 12.0)),
UplaodItems.dart(完成代码 Dart 文件以防万一有人需要它,这里的人正在选择,在表单上写描述并上传图片)
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ecom_app/Widgets/loadingwidget.dart';
import 'package:ecom_app/main.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'adminShiftOrders.dart';
class UploadPage extends StatefulWidget {
const UploadPage({Key? key}) : super(key: key);
@override
_UploadPageState createState() => _UploadPageState();
}
class _UploadPageState extends State<UploadPage> {
bool get wantKeepAlive =>true;
File? file;
TextEditingController _descriptionTEC=TextEditingController();
TextEditingController _priceTEC=TextEditingController();
TextEditingController _titleTEC=TextEditingController();
TextEditingController _shortInfoTEC=TextEditingController();
String productId=DateTime.now().microsecondsSinceEpoch.toString();
bool uploading=true;
@override
Widget build(BuildContext context) {
return file == null ? displayAdminHomeScreen() : displayAdminiUploadFormScreen();
}
displayAdminHomeScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(
onPressed: (){
Route route=MaterialPageRoute(builder: (c)=> AdminShiftOrders());
Navigator.pushReplacement(context, route);
},
icon: Icon(Icons.border_color,color: Colors.white,),
),
actions: [
FlatButton(
onPressed: (){
Route route=MaterialPageRoute(builder: (c)=> SplashScreen());
Navigator.pushReplacement(context, route);
},
child: Text('Logout',style: TextStyle(color: Colors.pink,fontSize: 16.0,
fontWeight: FontWeight.bold)))
],
),
body: getAdminHomeScreenBody(),
);
}
getAdminHomeScreenBody(){
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
child: Center(
child: Column
(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.shop_2,color: Colors.white,size: 200,),
Padding(
padding: EdgeInsets.only(top: 20.0),
child: RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(9.0)),
child: Text('Add New Items',style: TextStyle(color: Colors.white,fontSize: 20.0),),
color: Colors.green,
onPressed: (){
takeImage(context);
},
),
)
],
),)
);
}
takeImage(mcontex){
return showDialog(
context: mcontex,
builder: (con)
{
return SimpleDialog(
title: Text('Item Image',style: TextStyle(color: Colors.green,fontWeight: FontWeight.bold)),
children: [
SimpleDialogOption(
child: Text('Capture Imge With Camera',style: TextStyle(color: Colors.green),),
onPressed: (){
capturePhotoWithCamer();
},
),
SimpleDialogOption(
child: Text('Select Image from Gallery',style: TextStyle(color: Colors.green),),
onPressed: (){
pickPhotoFromGallery();
},
),
SimpleDialogOption(
child: Text('Cancel',style: TextStyle(color: Colors.green),),
onPressed: (){
Navigator.pop(context);
},
)
],
);
}
);
}
capturePhotoWithCamer() async{
final imagefile= await ImagePicker().pickImage(source:ImageSource.camera,maxHeight: 680.0,maxWidth: 970.0);
final _imagefile=File(imagefile!.path);
setState(() {
this.file=_imagefile;
});
}
pickPhotoFromGallery()async {
final imagefile= await ImagePicker().pickImage(source: ImageSource.gallery);
final _imageselected=File(imagefile!.path);
setState(() {
this.file=_imageselected;
});
}
displayAdminiUploadFormScreen(){
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
leading: IconButton(icon: Icon(Icons.arrow_back,color: Colors.white,),
onPressed: clearFormInfo(),
),
title: Text('New Product',style: TextStyle(color: Colors.white,fontSize: 24.0,fontWeight: FontWeight.bold),),
actions: [
FlatButton(onPressed: (){
uploading ? null: uploadImageandSaveItem();
},
child: Text('Add',style: TextStyle(color: Colors.pink,fontSize: 16.0,fontWeight: FontWeight.bold),)
),
],
),
body: ListView(
children: [
uploading ? circularProgress():Text(''),
Container(
height: 230.0,
width: MediaQuery.of(context).size.width*0.8,
child: Center(
child: AspectRatio
(aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(image:DecorationImage(image:FileImage(file!),fit:BoxFit.cover)),
),
),
),
),
Padding(padding: EdgeInsets.only(top: 12.0)),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _titleTEC,
decoration: InputDecoration(
hintText: 'Title',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _shortInfoTEC,
decoration: InputDecoration(
hintText: 'Short Info',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _descriptionTEC,
decoration: InputDecoration(
hintText: 'Description',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
ListTile(
leading: Icon(Icons.perm_device_information,color: Colors.pink,),
title: Container(
width: 250.0,
child: TextField(
keyboardType: TextInputType.number,
style: TextStyle(
color: Colors.deepOrangeAccent,
),
controller: _priceTEC,
decoration: InputDecoration(
hintText: 'Price',
hintStyle: TextStyle(color: Colors.deepOrange),
border: InputBorder.none
),
),
),
),
Divider(
color: Colors.deepOrangeAccent,
),
],
),
);
}
clearFormInfo(){
setState(() {
file=null;
_descriptionTEC.clear();
_priceTEC.clear();
_shortInfoTEC.clear();
_titleTEC.clear();
});
}
uploadImageandSaveItem()async{
setState(() {
uploading=true;
});
String imagedownloadUrl =await uploadItemImage(file);
saveItemInfo(imagedownloadUrl);
}
uploadItemImage(mfileimage)async{
final Reference reference=FirebaseStorage.instance.ref().child('items');
UploadTask uploadTask=reference.child('prodcut_$productId.jpg').putFile(mfileimage);
TaskSnapshot snapshot=await uploadTask.whenComplete(() => null);
String downloadUrl=await snapshot.ref.getDownloadURL();
return downloadUrl;
}
saveItemInfo(String downloadUrl){
final itemRef=FirebaseFirestore.instance.collection('items');
itemRef.doc(productId).set({
'shortInfo':_shortInfoTEC.text.trim(),
'longDescription':_descriptionTEC.text.trim(),
'price':_priceTEC.text.trim(),
'publishedDate':DateTime.now(),
'status':'available',
'thumbnailUrl': downloadUrl,
'title':_titleTEC.text.trim(),
});
setState(() {
file=null;
uploading=false;
productId=DateTime.now().millisecondsSinceEpoch.toString();
_descriptionTEC.clear();
_titleTEC.clear();
_shortInfoTEC.clear();
_priceTEC.clear();
});
}
}
更新
item.dart(这里需要上传到firestore的数据是json格式的)
import 'package:cloud_firestore/cloud_firestore.dart';
class ItemModel {
String? title;
String? shortInfo;
Timestamp? publishedDate;
String? thumbnailUrl;
String? longDescription;
String? status;
int? price;
ItemModel(
{required this.title,
required this.shortInfo,
required this.publishedDate,
required this.thumbnailUrl,
required this.longDescription,
required this.status,
required this.price,
});
ItemModel.fromJson(Map<String, dynamic> json) {
title = json['title'];
shortInfo = json['shortInfo'];
publishedDate = json['publishedDate'];
thumbnailUrl = json['thumbnailUrl'];
longDescription = json['longDescription'];
status = json['status'];
price = json['price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['shortInfo'] = this.shortInfo;
data['price'] = this.price;
if (this.publishedDate != null) {
data['publishedDate'] = this.publishedDate;
}
data['thumbnailUrl'] = this.thumbnailUrl;
data['longDescription'] = this.longDescription;
data['status'] = this.status;
return data;
}
}
class PublishedDate {
String? date;
PublishedDate({required this.date});
PublishedDate.fromJson(Map<String, dynamic> json) {
date = json['$date'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['$date'] = this.date;
return data;
}
}
firestore 图片
更新代码后的新错误
再次更新错误
当我点击控制台堆栈中的错误行时,它会将我带到我的 main.dart
当我点击控制台堆栈中的 #2 错误行时,它会将我带到一个名为“framwork.dart”的文件
当我点击 #3rd 错误行时,它再次将我带到“framwork.dart”文件中的功能
adminlogin.dart(此处管理员获取按钮以在 firebasefirestore 上上传项目)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ecom_app/Authentication/AuthnticationScreen.dart';
import 'package:ecom_app/DialogBox/errordialog.dart';
import 'package:ecom_app/Widgets/CustomTextField.dart';
import 'package:flutter/material.dart';
import 'Uploaditems.dart';
class Adminsignin extends StatelessWidget {
const Adminsignin({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
),
title: Text
(
'E-Shop',
style: TextStyle(
fontSize:55.0,color: Colors.white),
),
centerTitle: true,
),
body: AdminSignInPage(),
);
}
}
class AdminSignInPage extends StatefulWidget {
const AdminSignInPage({Key? key}) : super(key: key);
@override
_AdminSignInPageState createState() => _AdminSignInPageState();
}
class _AdminSignInPageState extends State<AdminSignInPage> {
final TextEditingController _adminController =TextEditingController();
final TextEditingController _passwordController =TextEditingController();
final GlobalKey<FormState> _formKey=GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
double _screenwidth=MediaQuery.of(context).size.width,_screenHeight=MediaQuery.of(context).size.height;
return SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.pink,Colors.lightGreenAccent],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0,1.0],
tileMode: TileMode.clamp,
)
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
alignment: Alignment.bottomCenter,
child: Image.asset(
'images/welcome.png',
height: 240.0,
width: 240.0,
),
),
Padding(
padding:EdgeInsets.all(8.0),
child: Text('Admin',
style: TextStyle(color: Colors.white38,fontSize: 28.0,fontWeight: FontWeight.bold),
),
),
Form(
key: _formKey,
child: Column(
children: [
customtextfield(
controller: _adminController,
data: Icons.person,
hinttext: 'ID',
isObsecure:false,
),
customtextfield(
controller: _passwordController,
data: Icons.lock,
hinttext: 'Password',
isObsecure:true,
),
SizedBox(
height: 25.0,
),
ElevatedButton(
onPressed: ()=>
_adminController.text.isNotEmpty&&_passwordController.text.isNotEmpty
? loginAdmin ()
:showDialog(
context: context,
builder: (c){
return ErrorDialog(message: 'Please Enter ID and Password');
}
),
style: ElevatedButton.styleFrom(primary: Colors.pink,onPrimary: Colors.yellow),
child:Text("Login"),
),
SizedBox(
height: 50.0,
),
Container(
height: 4.0,
width: _screenwidth*0.8,
color: Colors.pink,
),
SizedBox(
height: 10.0,
),
FlatButton.icon(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>AuthenticScreen( )));
},
icon: Icon(Icons.admin_panel_settings,color: Colors.pink,),
label: Text('I am not an Admin',style: TextStyle(color: Colors.pink,fontWeight: FontWeight.bold),),
),
SizedBox(
height: 50.0,
),
],
)
),
],
),
),
);
}
loginAdmin () {
FirebaseFirestore.instance.collection('admins').get().then((snapshot){
snapshot.docs.forEach((result){
if(result.data()['id'] != _adminController.text.trim())
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('ID is not Correct')));
}
else if(result.data()['password'] != _passwordController.text.trim())
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Passwod is not Correct')));
}
else
{
Scaffold.of(context).showSnackBar(SnackBar(content: Text('Welcome Admin, ' +result.data()['name'],)));
setState(() {
_adminController.text='';
_passwordController.text='';
});
Route route=MaterialPageRoute(builder: (c)=> UploadPage());
Navigator.pushReplacement(context, route);
}
});
});
}
}
【问题讨论】:
-
能否提供这部分的完整代码 -->
Below is the function where the error line points out to a bang(!) operator -
我已经提供了完整的代码。它由 UploadItem.dart 命名,您可以在“以下是错误行指向 bang(!) 运算符的函数”下找到它
-
对空值使用空检查运算符,Bang(!) 运算符问题已解决,对吗?这个问题与火力基地有关..
-
并且请将 RaisedButton 更改为提升按钮,将 flatbutton 更改为 textbutton,因为它们已被贬低。您还需要进行必要的更改。
标签: flutter dart null null-check