Когда виджет textfield_tag ​​перестраивается во второй раз, он выдает ошибку TextEditingController, которая использовалась после удаления

Когда виджет textfield_tag ​​перестраивается во второй раз, возникает ошибка TextEditingController использовался после удаления. Я показываю виджет на основе тумблера. Я попытался передать виджету TextFieldTagsController(), который я создаю в методе состояние инициализации(), но получаю ту же ошибку.

ПЕРЕД ПОКАЗОМ ВИДЖЕТА

Когда виджет textfield_tag ​​перестраивается во второй раз, он выдает ошибку TextEditingController, которая использовалась после удаления

ПОСЛЕ ПОКАЗА ВИДЖЕТА

Когда виджет textfield_tag ​​перестраивается во второй раз, он выдает ошибку TextEditingController, которая использовалась после удаления

ТЕПЕРЬ ПОСЛЕ ВТОРОГО РАЗА ПЕРЕКЛЮЧАЮ ПЕРЕКЛЮЧАТЕЛЬ

Когда виджет textfield_tag ​​перестраивается во второй раз, он выдает ошибку TextEditingController, которая использовалась после удаления

ВОТ КОД

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:marketplace/bloc/bloc.dart';
import 'package:marketplace/models/product.dart';
import 'package:image_picker/image_picker.dart';
import 'package:marketplace/screens/my_store_screen.dart';
import 'dart:io';
import 'package:textfield_tags/textfield_tags.dart';

import '../main.dart';
import '../utils/screen_utils.dart';

class AddProductScreenTwo extends StatefulWidget {
  static const routeName = '/add_product_screen_two';

  Product? _product;

  AddProductScreenTwo(this._product);

  @override
  _AddProductScreenTwoState createState() =>
      _AddProductScreenTwoState(_product);
}

class _AddProductScreenTwoState extends State<AddProductScreenTwo> {
  final _formKey = GlobalKey<FormState>();

  var bloc = getIt<Bloc>();

  late String _title, _description, _model, _sku, _price, _stock;
  String currencyDropDownValue = 'USD';
  String categoryDropDownValue = 'Shoes';
  String subcategoryDropDownValue = 'Sport';
  late String _colorDropDownValue, _sizeDropDownValue;
  List<String> currencies = [
    "USD",
    "THA",
  ];
  var categories = ['Shoes', 'Pants', 'Shirt', 'Smoking'];
  var _colorOptions = ['Red', 'Green', 'Yellow'];
  var _sizeOptions = ['L', 'M', 'S'];
  var subcategories = ['Sport', 'Casual'];
  List<XFile> _imageFileList = [];
  var _image;
  var imagePicker;

  bool _isUpdating = false;
  Product? _productToUpdate;
  int _deliveryMethodValue = 1;
  bool _hasVariant = false;

  // var _txtFieldTagController;

  _AddProductScreenTwoState(this._productToUpdate) {
    _colorDropDownValue = _colorOptions[0];
    _sizeDropDownValue = _sizeOptions[0];
  }

  @override
  void initState() {
    print("calling INITSTATE");
    // _txtFieldTagController = TextFieldTagsController();

    super.initState();
    imagePicker = new ImagePicker();
  }

  @override
  Widget build(BuildContext context) {
    ScreenUtils().init(context);
    return Scaffold(
      body: SafeArea(
        child: Form(
          key: _formKey,
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              // mainAxisSize: MainAxisSize.min,
              children: [
                Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: getProportionateScreenWidth(16),
                  ),
                  child: Column(
                    // mainAxisSize: MainAxisSize.min,
                    // crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        'Add New Product',
                        style: Theme.of(context).textTheme.headline3!.copyWith(
                              fontWeight: FontWeight.bold,
                            ),
                      ), // Title : Add New Product
                      SizedBox(
                        height: getProportionateScreenHeight(20),
                      ),
                      TextFormField(
                        initialValue: _productToUpdate == null
                            ? ""
                            : _productToUpdate!.name.toString(),
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _title = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'Title',
                            helperText: 'eg. Long Sleeve tshirt',
                            // errorText: _titleError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // Title field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      TextFormField(
                        initialValue: _productToUpdate == null
                            ? ""
                            : _productToUpdate!.brand.toString(),
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _description = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'Description',
                            // errorText: _brandError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // Description Field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      Text("Categories"), // Category selector label
                      Container(
                        padding: const EdgeInsets.all(6.0),
                        width: MediaQuery.of(context).size.width,
                        decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0)),
                        child: DropdownButtonHideUnderline(
                          child: DropdownButton<String>(
                            isExpanded: true,
                            value: categoryDropDownValue,
                            icon: const Icon(Icons.arrow_drop_down),
                            iconSize: 32,
                            elevation: 16,
                            style: const TextStyle(
                                fontSize: 20, color: Colors.black54),
                            onChanged: (String? newValue) {
                              setState(() {
                                categoryDropDownValue = newValue ?? "";
                              });
                            },
                            items: categories
                                .map<DropdownMenuItem<String>>((String value) {
                              return DropdownMenuItem<String>(
                                value: value,
                                child: Text(value),
                              );
                            }).toList(),
                          ),
                        ),
                      ), // Category selector field
                      SizedBox(
                        height: getProportionateScreenHeight(25),
                      ),
                      Text("Images"), // Image selector label
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      _imageFileList.length != 0
                          ? SizedBox(
                              height: 200,
                              child: ListView.builder(
                                scrollDirection: Axis.horizontal,
                                itemBuilder: (BuildContext context, int index) {
                                  return SizedBox(
                                    height: 200,
                                    width: 200,
                                    child: Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: Stack(children: [
                                        Image.file(
                                            File(_imageFileList[index].path)),
                                        Positioned(
                                          bottom: 5.0,
                                          right: 5.0,
                                          child: IconButton(
                                              onPressed: () => removeImage(
                                                  _imageFileList[index]),
                                              icon: Icon(
                                                Icons.delete_forever,
                                                color: Colors.red,
                                              )),
                                        ),
                                      ]),
                                    ),
                                  );
                                },
                                itemCount: _imageFileList.length,
                              ),
                            )
                          : Text("no image"),
                      IconButton(
                          onPressed: () => pickMultipleImages(),
                          icon: Icon(Icons.add_a_photo_outlined)),
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      TextFormField(
                        initialValue: _productToUpdate == null
                            ? ""
                            : _productToUpdate!.price.toString(),
                        keyboardType: TextInputType.number,
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _price = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'Price',
                            // errorText: _priceError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // Price Field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      TextFormField(
                        initialValue: _productToUpdate == null
                            ? ""
                            : _productToUpdate!.sku.toString(),
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _sku = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'SKU',
                            // errorText: _skuError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // SKU Field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      TextFormField(
                        keyboardType: TextInputType.number,
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _stock = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'Stock Quantity',
                            // errorText: _stockError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // Stock Quantity field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      Text("Shipping methods"), // Delivery options label
                      ListTile(
                          title: Text("Home Delivery"),
                          leading: Radio<int>(
                            value: 1,
                            groupValue: _deliveryMethodValue,
                            onChanged: (value) {
                              if (value != null) {
                                setState(() {
                                  _deliveryMethodValue = value;
                                });
                              }
                            },
                          )), // Home delivery option
                      ListTile(
                          title: Text("Pick up in store"),
                          leading: Radio<int>(
                            value: 2,
                            groupValue: _deliveryMethodValue,
                            onChanged: (value) {
                              if (value != null) {
                                setState(() {
                                  _deliveryMethodValue = value;
                                });
                              }
                            },
                          )), // Pick up in store option
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      TextFormField(
                        keyboardType: TextInputType.number,
                        initialValue: _productToUpdate == null
                            ? ""
                            : _productToUpdate!.sku.toString(),
                        cursorColor: Theme.of(context).cursorColor,
                        validator: (text) => cannotBeEmptyValidator(text),
                        onChanged: (value) {
                          _sku = value;
                        },
                        decoration: InputDecoration(
                            labelText: 'Weight in KG',
                            // errorText: _skuError,
                            border: OutlineInputBorder(
                                borderRadius: const BorderRadius.all(
                                    Radius.circular(0.0)))),
                      ), // Weight Field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      Text("Variants"), // Variants label
                      Container(
                        padding: const EdgeInsets.all(6.0),
                        decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0)),
                        child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Product has variant",
                                style: Theme.of(context)
                                    .textTheme
                                    .bodyText1!
                                    .copyWith(
                                      fontWeight: FontWeight.bold,
                                    ),
                              ),
                              Switch(
                                  value: _hasVariant,
                                  onChanged: (val) {
                                    setState(() {
                                      _hasVariant = val;
                                    });
                                  })
                            ]),
                      ), // Variants field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      _hasVariant
                          ? TextFieldTags(
                              textSeparators: [
                                " ", //seperate with space
                                ',' //sepearate with comma as well
                              ],
                              initialTags: _colorOptions,
                              onTag: (tag) => _colorOptions.add(tag),
                              onDelete: (tag) => _colorOptions.remove(tag),
                              tagsStyler: TagsStyler(
                                  //styling tag style
                                  tagTextStyle:
                                      TextStyle(fontWeight: FontWeight.normal),
                                  tagDecoration: BoxDecoration(
                                    color: Colors.blue[100],
                                    borderRadius: BorderRadius.circular(0.0),
                                  ),
                                  tagCancelIcon: Icon(Icons.cancel,
                                      size: 18.0, color: Colors.blue[900]),
                                  tagPadding: EdgeInsets.all(6.0)),
                              textFieldStyler: TextFieldStyler(
                                  //styling tag text field
                                  textFieldBorder: OutlineInputBorder(
                                      borderSide: BorderSide(
                                          color: Colors.blue, width: 2))),
                              // textFieldTagsController: _txtFieldTagController,
                            )
                          : Container(),

                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      Container(
                        padding: const EdgeInsets.all(6.0),
                        decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.circular(0.0)),
                        child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                "Show to customers",
                                style: Theme.of(context)
                                    .textTheme
                                    .bodyText1!
                                    .copyWith(
                                      fontWeight: FontWeight.bold,
                                    ),
                              ),
                              Switch(
                                  value: true,
                                  onChanged: (val) {
                                    //TODO update the product visibility value online
                                    // setState(() {
                                    //   switchValue = val;
                                    // });
                                  })
                            ]),
                      ), // Availability field
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      StreamBuilder<bool>(
                          stream: bloc.isPostingProduct,
                          builder: (context, snapshot) {
                            print("SNAPSHOT: ${snapshot.data}");

                            if (snapshot.data == true) {
                              // Product is being posted
                              return CircularProgressIndicator();
                            }
                            return Container();
                          }),
                      SizedBox(
                        height: getProportionateScreenHeight(15),
                      ),
                      ElevatedButton(
                        onPressed: () {
                          _submit();
                        },
                        child: Text('ADD PRODUCT',
                            style: TextStyle(fontWeight: FontWeight.bold)),
                      ), // Add product button
                    ],
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }


  Future pickMultipleImages() async {
    try {
      var images = await ImagePicker().pickMultiImage();
      setState(() {
        _imageFileList.addAll(images!);
      });
      for (var image in _imageFileList) {
        print("Multiple images picked : " + image.path);
      }
    } catch (e) {
      print("Error : $e");
    }
  }

  void removeImage(XFile imageFile) {
    setState(() {
      _imageFileList.remove(imageFile);
    });
  }

  void _submit() async {
    //TODO
    // validate all the form fields
    if (_formKey.currentState!.validate()) {
      ProductTwo product = ProductTwo(
        title: _title,
        description: _description,
        sku: _sku,
        price: double.parse(_price),
      );

      print("POSTING PRODUCT : $product");
      var result = await bloc.postProduct(product);
      if (result) {
        const snackBar = SnackBar(
          content: Text('Your product was saved successfully'),
        );

        ScaffoldMessenger.of(context).showSnackBar(snackBar);

        Navigator.of(context).pushReplacementNamed(MyStoreScreen.routeName);
      }
    }
  }

  _showPostSuccessDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Container(
            height: 120,
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Icon(Icons.done, size: 64, color: Colors.green),
                  SizedBox(
                    height: getProportionateScreenHeight(20),
                  ),
                  Text(
                    "Your product was successfully saved",
                    style: TextStyle(color: Colors.green),
                  ),
                ]),
          ),
        );
      },
    );
  }

  String? cannotBeEmptyValidator(String? text) {
    if (text == null || text.isEmpty) {
      return 'Can\'t be empty';
    }
    return null;
  }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
13
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте добавить «монтированный», чтобы проверить, не удален ли виджет.

_hasVariant && mounted
                          ? TextFieldTags(
                        textSeparators: [
                          " ", //seperate with space
                          ',' //sepearate with comma as well
                        ],
                        initialTags: _colorOptions,
                        onTag: (tag) => _colorOptions.add(tag),
                        onDelete: (tag) => _colorOptions.remove(tag),
                        tagsStyler: TagsStyler(
                          //styling tag style
                            tagTextStyle:
                            TextStyle(fontWeight: FontWeight.normal),
                            tagDecoration: BoxDecoration(
                              color: Colors.blue[100],
                              borderRadius: BorderRadius.circular(0.0),
                            ),
                            tagCancelIcon: Icon(Icons.cancel,
                                size: 18.0, color: Colors.blue[900]),
                            tagPadding: EdgeInsets.all(6.0)),
                        textFieldStyler: TextFieldStyler(
                          //styling tag text field
                            textFieldBorder: OutlineInputBorder(
                                borderSide: BorderSide(
                                    color: Colors.blue, width: 2))),
                        // textFieldTagsController: _txtFieldTagController,
                      )
                          : Container(),
Ответ принят как подходящий

Это ошибка в версии 1.4.4 библиотеки textfield_tags. В настоящее время он хранит TextEditingController и FocusNode в статических полях и повторно использует их для каждого экземпляра TextFieldTags.

Единственное, что вы можете сделать, это зарегистрировать проблему на трекер и перейти на версию 1.4.3, пока проблема не будет исправлена ​​в более поздней версии.

Спасибо, работает с версией 1.4.3. Зарегистрирует проблему на трекере

Armando Sudi 18.03.2022 10:21

Другие вопросы по теме