【问题标题】:Null check operator used on a null value, Bang(!) Operator Issue空值检查运算符,Bang(!) 运算符问题
【发布时间】: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


【解决方案1】:

希望这会有所帮助..


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;
  late File file;
  TextEditingController _descriptionTEC=TextEditingController();
  TextEditingController _priceTEC=TextEditingController();
  TextEditingController _titleTEC=TextEditingController();
  TextEditingController _shortInfoTEC=TextEditingController();
  String productId=DateTime.now().microsecondsSinceEpoch.toString();
  bool uploading=false;
  @override
  Widget build(BuildContext context) {
    return displayAdminiUploadFormScreen();
    /*
    // This will execute but gives a warning:
    Reference:
    https://dart.dev/tools/diagnostic-messages#unnecessary_null_comparison
    return file == null ? displayAdminHomeScreen() : displayAdminiUploadFormScreen();
    // equivalent to below code
    if (file != null){
      return displayAdminiUploadFormScreen();
    } else {
      return displayAdminHomeScreen();
    }
    // I you want to remove the warning the  follow the code which is not commented*/
  }
  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);
  }
  @override
  void initState() {
    super.initState();
    saveItemInfo('').whenComplete(Closure: () => Null);
    uploadItemImage('').whenComplete(Closure: () => Null);
  }
  uploadItemImage(mfileimage)async{
    uploading = true;
    final Reference reference=FirebaseStorage.instance.ref().child('items');
    UploadTask uploadTask=reference.child('prodcut_$productId.jpg').putFile(mfileimage);
    TaskSnapshot snapshot=await uploadTask.whenComplete((){
      setState(() {});
    });
    String downloadUrl=await snapshot.ref.getDownloadURL();
    return downloadUrl;
  }

  saveItemInfo(String downloadUrl){
    uploading = true;
    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(() {


      uploading=false;
      productId=DateTime.now().millisecondsSinceEpoch.toString();
      _descriptionTEC.clear();
      _titleTEC.clear();
      _shortInfoTEC.clear();
      _priceTEC.clear();
    });
  }

}

【讨论】:

猜你喜欢
  • 2021-10-29
  • 2021-01-24
  • 2022-07-06
  • 2021-12-03
  • 2021-07-09
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多