我正在try 在空数组中添加项.我正在使用DIO包发送发帖请求.所有其他代码都工作正常.但在这里,我被这个问题难住了.我取了一个空array.然后,我try 使用setState函数将项添加到空列表中.每次按下 list ,我都会把它打印出来.但我得到的是空array.

实际上,我正在try 将产品添加到空数组中并发送POST请求.

以下是我的代码:

Consumer<ProductController>(
                        builder: ((context, value, child) {
                          // log('${value.products[0].results?.length.toString()}');
                          if (value.products.isNotEmpty) {
                            return Container(
                                height: maxHeight * 0.3,
                                child: ListView.builder(
                                  itemCount: value.products[0].results!.length,
                                  itemBuilder: (context, index) {
                                    return Card(
                                      child: ListTile(
                                        title: Text(value
                                            .products[0].results![index].name!),
                                        leading: IconButton(
                                          icon: const Icon(Icons.add),
                                          onPressed: () {
                                            setState(() {
                                              _lists.add(value.products[0]
                                                  .results![index].id);
                                              _lists = productIds;
                                              print("LISTS +>>>> $_lists");
                                            });
                                          },
                                        ),
                                        trailing: const Icon(Icons.done),
                                      ),
                                    );
                                  },
                                ));
                          } else {
                            return const CircularProgressIndicator();
                          }
                        }),
                      ),

这是我的模特:

class DisplayModel {
  String? status;
  List<Results>? results;

  DisplayModel({this.status, this.results});

  DisplayModel.fromJson(Map<String, dynamic> json) {
    status = json['status'];
    if (json['results'] != null) {
      results = <Results>[];
      json['results'].forEach((v) {
        results!.add(new Results.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['status'] = this.status;
    if (this.results != null) {
      data['results'] = this.results!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Results {
  int? id;
  List<Products>? products;
  List<Catalogs>? catalogs;
  String? name;
  Null? description;
  String? category;
  String? templateName;
  Null? bannerText;

  Results(
      {this.id,
      this.products,
      this.catalogs,
      this.name,
      this.description,
      this.category,
      this.templateName,
      this.bannerText});

  Results.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    if (json['products'] != null) {
      products = <Products>[];
      json['products'].forEach((v) {
        products!.add(new Products.fromJson(v));
      });
    }
    if (json['catalogs'] != null) {
      catalogs = <Catalogs>[];
      json['catalogs'].forEach((v) {
        catalogs!.add(new Catalogs.fromJson(v));
      });
    }
    name = json['name'];
    description = json['description'];
    category = json['category'];
    templateName = json['template_name'];
    bannerText = json['banner_text'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    if (this.products != null) {
      data['products'] = this.products!.map((v) => v.toJson()).toList();
    }
    if (this.catalogs != null) {
      data['catalogs'] = this.catalogs!.map((v) => v.toJson()).toList();
    }
    data['name'] = this.name;
    data['description'] = this.description;
    data['category'] = this.category;
    data['template_name'] = this.templateName;
    data['banner_text'] = this.bannerText;
    return data;
  }
}

class Products {
  int? id;
  String? name;
  Null? unit;
  String? price;
  Null? salePrice;
  String? image;
  Null? category;
  Null? badge;

  Products(
      {this.id,
      this.name,
      this.unit,
      this.price,
      this.salePrice,
      this.image,
      this.category,
      this.badge});

  Products.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    unit = json['unit'];
    price = json['price'];
    salePrice = json['sale_price'];
    image = json['image'];
    category = json['category'];
    badge = json['badge'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['unit'] = this.unit;
    data['price'] = this.price;
    data['sale_price'] = this.salePrice;
    data['image'] = this.image;
    data['category'] = this.category;
    data['badge'] = this.badge;
    return data;
  }
}

class Catalogs {
  int? id;
  Null? name;
  Null? unit;
  Null? price;
  Null? salePrice;
  String? image;
  Null? video;
  Null? badge;

  Catalogs(
      {this.id,
      this.name,
      this.unit,
      this.price,
      this.salePrice,
      this.image,
      this.video,
      this.badge});

  Catalogs.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    unit = json['unit'];
    price = json['price'];
    salePrice = json['sale_price'];
    image = json['image'];
    video = json['video'];
    badge = json['badge'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['unit'] = this.unit;
    data['price'] = this.price;
    data['sale_price'] = this.salePrice;
    data['image'] = this.image;
    data['video'] = this.video;
    data['badge'] = this.badge;
    return data;
  }
}

这是我的Post控制器:

Future<bool> addDisplay(String name, String category, String templateName,
      File catalogsImage, File catalogsVideo, List<Products> productIds) async {
    try {
      // String fileName = catalogsImage.path.split('/').last;
      var token = localStorage.getItem('access');
      Dio dio = Dio();
      FormData formData = FormData.fromMap({
        "name": name,
        "category": category,
        "template_name": templateName,
        "catalogs[0]image": await MultipartFile.fromFile(catalogsImage.path),
        "catalogs[0]video": await MultipartFile.fromFile(catalogsVideo.path),
        "products": productIds
      });

      var response = await dio.post(url,
          data: formData,
          options: Options(headers: {"Authorization": "Bearer $token"}));

      if (response.statusCode == 200) {
        notifyListeners();
        return true;
      } else {
        return false;
      }
    } on DioError catch (e) {
      print(e);
      return false;
    }
  }

以下是前端的完整代码:

// ignore_for_file: sized_box_for_whitespace
import 'dart:developer';

import 'package:digitaldisplay/controllers/DisplayController.dart';
import 'package:digitaldisplay/controllers/ProductController.dart';
import 'package:digitaldisplay/models/DisplayModel.dart';
import 'package:digitaldisplay/views/widgets/Display.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import 'dart:io';

class CreateDisplayMobile extends StatefulWidget {
  const CreateDisplayMobile({super.key});

  @override
  State<CreateDisplayMobile> createState() => _CreateDisplayMobileState();
}

class _CreateDisplayMobileState extends State<CreateDisplayMobile> {
  final ImagePicker picker = ImagePicker();

  String _name = "";
  String _category = "";
  String _templateName = "";
  File? catalogImage;
  File? _catalogVideo;
  List<Products> productIds = [];

  final _form = GlobalKey<FormState>();
  void _addDisplay() async {
    var isValid = _form.currentState!.validate();
    if (!isValid) {
      return;
    }
    _form.currentState!.save();
    bool create = await Provider.of<DisplayController>(context, listen: false)
        .addDisplay(_name, _category, _templateName, catalogImage!,
            _catalogVideo!, productIds);
    if (create) {
      print(create);
      showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text("Created"),
              actions: [
                ElevatedButton(
                  child: const Text("Return"),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          });
    } else {
      showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text("Failed to create display!"),
              actions: [
                ElevatedButton(
                  child: const Text("Return"),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ],
            );
          });
    }
  }

  @override
  void initState() {
    Provider.of<DisplayController>(context, listen: false).getDisplays();
    Provider.of<ProductController>(context, listen: false).getProducts();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    List _lists = [];
    final ButtonStyle buttonStyle1 = ElevatedButton.styleFrom(
      backgroundColor: const Color(0xFFc3232a),
      shape: const StadiumBorder(),
      minimumSize: const Size(100, 50),
    );
    final ButtonStyle buttonStyle2 = ElevatedButton.styleFrom(
      backgroundColor: const Color(0xFFc3232a),
      shape: const StadiumBorder(),
      minimumSize: const Size(100, 50),
    );
    final ButtonStyle buttonStyle3 = ElevatedButton.styleFrom(
      backgroundColor: const Color(0xFF111111),
      shape: const StadiumBorder(),
      minimumSize: const Size(100, 50),
    );

    double maxHeight = MediaQuery.of(context).size.height;
    double maxWidth = MediaQuery.of(context).size.width;

    return Scaffold(
        // backgroundColor: Colors.deepPurple[200],
        appBar: AppBar(
          elevation: 0,
          backgroundColor: const Color(0xFF111111),
          title: const Text(
            "Digital Display Generator",
            textAlign: TextAlign.end,
          ),
        ),
        body: SingleChildScrollView(
          child: Column(children: [
            const SizedBox(
              height: 10,
            ),
            Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Consumer<DisplayController>(
                  builder: (context, value, child) {
                    log('${value.displays[0].results?.length.toString()}');
                    return Container(
                      height: maxHeight * 0.6,
                      width: maxWidth * 0.9,
                      child: GridView.count(
                        crossAxisSpacing: 5,
                        crossAxisCount: 1,
                        scrollDirection: Axis.horizontal,
                        children: List.generate(
                            value.displays.isNotEmpty
                                ? value.displays[0].results!.length
                                : 0, (i) {
                          return Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: DisplayCard(
                                displayName:
                                    value.displays[0].results![i].name!,
                                displayImage: value.displays[0].results![i]
                                    .catalogs![0].image!,
                                id: value.displays[0].results![i].id!),
                          );
                        }),
                      ),
                    );
                  },
                ),
              ],
            ),
            Form(
              key: _form,
              child: Center(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Padding(
                        padding: EdgeInsets.all(10.0),
                        child: Text(
                          "Enter Name",
                        )),
                    Padding(
                      padding: EdgeInsets.all(10),
                      child: TextFormField(
                        validator: (v) {
                          if (v!.isEmpty) {
                            return "Please Enter a valid name";
                          } else {
                            return null;
                          }
                        },
                        onSaved: (value) {
                          _name = value as String;
                        },
                        autofocus: false,
                        style: const TextStyle(
                            fontSize: 15.0, color: Colors.black),
                        decoration: InputDecoration(
                          hintText: 'Name',
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding: const EdgeInsets.only(
                              left: 14.0, bottom: 6.0, top: 8.0),
                          focusedBorder: OutlineInputBorder(
                            borderSide: const BorderSide(
                                color: Color.fromARGB(255, 73, 57, 55)),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                          enabledBorder: UnderlineInputBorder(
                            borderSide: const BorderSide(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                        ),
                      ),
                    ),
                    const Padding(
                        padding: EdgeInsets.all(10.0),
                        child: Text(
                          "Enter Template Name",
                        )),
                    Padding(
                      padding: EdgeInsets.all(10),
                      child: TextFormField(
                        validator: (v) {
                          if (v!.isEmpty) {
                            return "Please Enter a valid name";
                          } else {
                            return null;
                          }
                        },
                        onSaved: (value) {
                          _templateName = value as String;
                        },
                        autofocus: false,
                        style: const TextStyle(
                            fontSize: 15.0, color: Colors.black),
                        decoration: InputDecoration(
                          hintText: 'Template Name',
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding: const EdgeInsets.only(
                              left: 14.0, bottom: 6.0, top: 8.0),
                          focusedBorder: OutlineInputBorder(
                            borderSide: const BorderSide(
                                color: Color.fromARGB(255, 73, 57, 55)),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                          enabledBorder: UnderlineInputBorder(
                            borderSide: const BorderSide(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                        ),
                      ),
                    ),
                    const Padding(
                        padding: EdgeInsets.all(10.0),
                        child: Text(
                          "Enter Category Name",
                        )),
                    Padding(
                      padding: EdgeInsets.all(10),
                      child: TextFormField(
                        validator: (v) {
                          if (v!.isEmpty) {
                            return "Please Enter a valid name";
                          } else {
                            return null;
                          }
                        },
                        onSaved: (value) {
                          _category = value as String;
                        },
                        autofocus: false,
                        style: const TextStyle(
                            fontSize: 15.0, color: Colors.black),
                        decoration: InputDecoration(
                          hintText: 'Category Name',
                          filled: true,
                          fillColor: Colors.white,
                          contentPadding: const EdgeInsets.only(
                              left: 14.0, bottom: 6.0, top: 8.0),
                          focusedBorder: OutlineInputBorder(
                            borderSide: const BorderSide(
                                color: Color.fromARGB(255, 73, 57, 55)),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                          enabledBorder: UnderlineInputBorder(
                            borderSide: const BorderSide(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0),
                          ),
                        ),
                      ),
                    ),
                    const Padding(
                        padding: EdgeInsets.all(10.0),
                        child: Text(
                          "Select Product",
                        )),
                    Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Consumer<ProductController>(
                        builder: ((context, value, child) {
                          // log('${value.products[0].results?.length.toString()}');
                          if (value.products.isNotEmpty) {
                            return Container(
                                height: maxHeight * 0.3,
                                child: ListView.builder(
                                  itemCount: value.products[0].results!.length,
                                  itemBuilder: (context, index) {
                                    return Card(
                                      child: ListTile(
                                        title: Text(value
                                            .products[0].results![index].name!),
                                        leading: IconButton(
                                          icon: const Icon(Icons.add),
                                          onPressed: () {
                                            setState(() {
                                              _lists.add(value.products[0]
                                                  .results![index].id);
                                              // _lists = productIds;
                                              print("LISTS +>>>> $productIds");
                                            });
                                          },
                                        ),
                                        trailing: const Icon(Icons.done),
                                      ),
                                    );
                                  },
                                ));
                          } else {
                            return const CircularProgressIndicator();
                          }
                        }),
                      ),
                    ),
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: ElevatedButton(
                            onPressed: () {
                              _getImageFromGallery();
                              // displayController.createDisplay(
                              //     "name", "category", "templateName", "1");
                            },
                            child: Text("Add Image"),
                            style: buttonStyle1,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: ElevatedButton(
                            onPressed: () {
                              _getVideoFromGallery();
                              // displayController.createDisplay(
                              //     "name", "category", "templateName", "1");
                            },
                            child: Text("Add Video"),
                            style: buttonStyle1,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: ElevatedButton(
                            onPressed: () {
                              _addDisplay();
                            },
                            child: Text("Add Display"),
                            style: buttonStyle2,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ]),
        ));
  }

  void _getImageFromGallery() async {
    XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
    if (pickedFile != null) {
      setState(() {
        catalogImage = File(pickedFile.path);
      });
    }
  }

  void _getVideoFromGallery() async {
    XFile? filepick = await picker.pickImage(source: ImageSource.gallery);
    if (filepick != null) {
      setState(() {
        _catalogVideo = File(filepick.path);
      });
    }
  }
}

因此,在添加到空列表后,我想保存它.我如何才能获得这一点?我有什么解决办法吗?

推荐答案

第一个问题,你的主要问题是列表_lists是空的,尽管向列表中添加了值.

您在Build方法中声明了_lists变量:

@override
Widget build(BuildContext context) {
  List _lists = []; // <---- this line

  ...
}

...它将在每次状态发生变化时重新声明_lists变量,就像您在向_lists加值时调用setState一样:

setState(() {
  _lists.add(value.products[0].results![index].id);
  _lists = productIds;

  print("LISTS +>>>> $_lists");
});

因此,解决方案是将List _lists = [];从Build方法声明到_CreateDisplayMobileState类,使其成为顶级类变量.

class _CreateDisplayMobileState extends State<CreateDisplayMobile> {
  List _lists = [];

  ...
}

但是_lists = productIds;让我想到,您试图将_lists变量的值赋给productIds变量,该值为空,并且通过查看完整代码不会在任何地方进行更新.因此,这毫无意义.你必须把它取下来.

更新:

setState(() {
  _lists.add(value.products[0].results![index].id);
  
  // removed: _lists = productIds;

  print("LISTS +>>>> $_lists");
});

MAIN:

此外,由于您希望发布添加到_lists变量中的products id,因此同时拥有变量_listsproductIds是没有意义的.只需删除_lists变量,将productsIds变量的类型从List<Product> productIds更改为List<int> productIdsaddDisplay方法productIds参数,然后直接将产品ID添加到productIds.

setState(() {
  productIds.add(value.products[0].results![index].id);

  print("LISTS +>>>> $productIds");
});

干杯????.

Flutter相关问答推荐

我遇到了一个问题,从showDialogue()调用Navigator.pop()两次导致屏幕空白

带有可滚动页面(不包括分页区)的Flutter 页面视图

audioQuery不会等待判断存储权限

IsScrollable为True时如何删除Flutter 选项卡栏左侧填充

遇到图像路径格式问题

无效参数(S):隔离消息中的非法参数:try 旋转图像时对象不可发送

构建方法中的性能声明小部件

从图标启动器打开时,VSCode未检测到Web设备

Riverpod 2.0-如何使用FutureOr和AutoDisposeSyncNotificationer处理api状态代码?

Flutter Xcode 15 错误(Xcode):DT_TOOLCHAIN_DIR 无法用于判断 LIBRARY_SEARCH_PATHS

显示图像的放大部分

Flutter 自定义对齐

Paypal 支付网关添加带有 magento 2 网络详细信息用户名、密码、签名 Magento 2 的 flutter 应用程序?

Flutter canvas 绘制不同 colored颜色 的原始点

如何为文本主题设置多种 colored颜色 ?

如何将 chrome web 模拟器添加到 vs code

如何将 List 转换为 String []?

statefulWidget 无法进行所需更改的问题

Flutter RawMaterialButton 常量相对大小

Flutter Web Responsiveness 效率不高