【问题标题】:Flutter add value from custom TextFormField and automatically show the value in another customtextformfieldFlutter 从自定义 TextFormField 添加值并自动在另一个 customtextformfield 中显示该值
【发布时间】:2021-09-30 12:04:11
【问题描述】:

我有一个自定义文本字段,在我的应用程序中,用户在带有标签数量的文本字段中输入金额,输入的金额应乘以另一个文本字段中的值(此文本字段中的值来自上一页的列表称为价格)。总计应在另一个名为总计的文本字段中自动计算。以下是我尝试过的代码。

import 'package:flutter/material.dart';
import 'package:kingstar/res/custom_colors.dart';

class CustomFormField extends StatelessWidget {
  const CustomFormField({
    Key? key,
    required TextEditingController controller,
    // required FocusNode focusNode,
    required TextInputType keyboardType,
    required TextInputAction inputAction,
    required String label,
    required String hint,
    required Function(String value) validator,
    required Function(String value) onChanged,
    this.isObscure = false,
    this.isCapitalized = false,
    this.maxLines = 1,
    this.isLabelEnabled = true,
    this.readOnly = false,
  })  : _emailController = controller,
        // _emailFocusNode = focusNode,
        _keyboardtype = keyboardType,
        _inputAction = inputAction,
        _label = label,
        _hint = hint,
        _validator = validator,
        super(key: key);

  final TextEditingController _emailController;
  // final FocusNode _emailFocusNode;
  final TextInputType _keyboardtype;
  final TextInputAction _inputAction;
  final String _label;
  final String _hint;
  final bool isObscure;
  final bool isCapitalized;
  final int maxLines;
  final bool isLabelEnabled;
  final Function(String) _validator;
  final bool readOnly;

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      maxLines: maxLines,
      controller: _emailController,
      readOnly: readOnly,
      // focusNode: _emailFocusNode,
      keyboardType: _keyboardtype,
      obscureText: isObscure,
      textCapitalization:
      isCapitalized ? TextCapitalization.words : TextCapitalization.none,
      textInputAction: _inputAction,
      style: TextStyle(color: Colors.white),
      cursorColor: CustomColors.firebaseYellow,
      validator: (value) => _validator(value!),
      decoration: InputDecoration(
        labelText: isLabelEnabled ? _label : null,
        labelStyle: TextStyle(color: CustomColors.firebaseYellow),
        hintText: _hint,
        hintStyle: TextStyle(
          color: Colors.white,
        ),
        errorStyle: TextStyle(
          color: Colors.redAccent,
          fontWeight: FontWeight.bold,
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8.0),
          borderSide: BorderSide(
            color: CustomColors.firebaseAmber,
            width: 2,
          ),
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8.0),
          borderSide: BorderSide(
            color: CustomColors.firebaseGrey.withOpacity(0.5),
          ),
        ),
        errorBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8.0),
          borderSide: BorderSide(
            color: Colors.redAccent,
            width: 2,
          ),
        ),
        focusedErrorBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8.0),
          borderSide: BorderSide(
            color: Colors.redAccent,
            width: 2,
          ),
        ),
      ),
    );
  }
}
class EditItemForm extends StatefulWidget {



  final String currentName;
  final String currentPrice;
  final String currentQuantity;
  final String documentId;

  const EditItemForm({
    required this.currentName,
    required this.currentPrice,
    required this.currentQuantity,
    required this.documentId,
  });

  @override
  _EditItemFormState createState() => _EditItemFormState();
}

class _EditItemFormState extends State<EditItemForm> {
  final _editItemFormKey = GlobalKey<FormState>();

  final DocumentReference docId = _salesCollection.doc();

  bool _isProcessing = false;


  late TextEditingController _nameController;
  late TextEditingController _priceController;
  late TextEditingController _quantityAvailableController;
  late TextEditingController _quantityController;
  late TextEditingController _totalController;
  int? _total = 0;


  late SharedPreferences sharedPreferences;

  late String documentId = "", buyer_name = "", buyer_phonenumber="", buyer_email="", buyer_address="", seller_name="", seller_location = "";
 late int total;

  void _onChange() {
    setState(() {
      _total = (int.parse( widget.currentPrice) * int.parse(_quantityController.text));
      print(int.parse( widget.currentPrice) * int.parse(_quantityController.text));
    });
  }

  textListener() {
    _total = (int.parse(_priceController.text) * int.parse(_quantityController.text));
    print("Current Text is ${_total.toString()}");
  }


  @override
  void initState() {
    _nameController = TextEditingController(
      text: widget.currentName,
    );
    _priceController = TextEditingController(
      text: widget.currentPrice,
    );
    _quantityAvailableController = TextEditingController(
      text: widget.currentQuantity,
    );
    _quantityController = TextEditingController(
        text: widget.currentQuantity,
    );

    _totalController = TextEditingController(
      text: widget.currentQuantity,
    );

    super.initState();

    _onChange();

    _quantityController.addListener(textListener);
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Form(
        key: _editItemFormKey,
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.only(
                left: 8.0,
                right: 8.0,
                bottom: 24.0,
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  SizedBox(height: 24.0),
                  Text(
                    'Feed Name',
                    style: TextStyle(
                      color: CustomColors.firebaseGrey,
                      fontSize: 22.0,
                      letterSpacing: 1,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  CustomFormField(
                    readOnly: true,
                    isLabelEnabled: false,
                    controller: _nameController,
                    keyboardType: TextInputType.text,
                    inputAction: TextInputAction.next,
                    validator: (value) => Validator.validateField(
                      value: value,
                    ),
                    label: 'Feed',
                    hint: 'Feed Name', onChanged: (String value) {  },
                  ),
                  SizedBox(height: 24.0),
                  Text(
                    'Price',
                    style: TextStyle(
                      color: CustomColors.firebaseGrey,
                      fontSize: 22.0,
                      letterSpacing: 1,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  CustomFormField(
                    // readOnly: true,
                    isLabelEnabled: false,
                    controller: _priceController,
                    keyboardType: TextInputType.text,
                    inputAction: TextInputAction.done,
                    validator: (value) => Validator.validateField(
                      value: value,
                    ),
                    label: 'Price',
                    hint: 'Price for' + widget.currentName,
                    onChanged: (value) => _onChange,
                  ),
                  SizedBox(height: 24,),
                  Text(
                    'Quanity Available',
                    style: TextStyle(
                      color: CustomColors.firebaseGrey,
                      fontSize: 22.0,
                      letterSpacing: 1,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  CustomFormField(
                    readOnly: true,
                    isLabelEnabled: false,
                    controller: _quantityAvailableController,
                    keyboardType: TextInputType.number,
                    inputAction: TextInputAction.done,
                    validator: (value) => Validator.validateField(
                      value: value,
                    ),
                    label: 'Quantity',
                    hint: 'Quantity available for' + widget.currentName,
                    onChanged: (value) => _onChange,
                  ),
                  SizedBox(height: 24,),
                  Text(
                    'Quanity ',
                    style: TextStyle(
                      color: CustomColors.firebaseGrey,
                      fontSize: 22.0,
                      letterSpacing: 1,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  CustomFormField(
                    isLabelEnabled: false,
                    controller: _quantityController,
                    keyboardType: TextInputType.number,
                    inputAction: TextInputAction.done,
                    validator: (value) => Validator.validateField(
                      value: value,
                    ),
                    label: 'Quantity',
                    hint: 'Enter your quantity',
                    onChanged: (value) => _onChange,
                  ),
                  SizedBox(height: 24,),
                  Text(
                    'Total ',
                    style: TextStyle(
                      color: CustomColors.firebaseGrey,
                      fontSize: 22.0,
                      letterSpacing: 1,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(height: 8.0),
                  CustomFormField(
                    readOnly: true,
                    isLabelEnabled: false,
                    controller: _totalController,
                    keyboardType: TextInputType.number,
                    inputAction: TextInputAction.done,
                    validator: (value) => Validator.validateField(
                      value: value,
                    ),
                    label: 'Total',
                    hint: 'Total',
                    onChanged: (String value) {  },
                  ),
                  Text(
                      _total!.toString()
                  )
                ],
              ),
            ),
            _isProcessing
                ? Padding(
              padding: const EdgeInsets.all(16.0),
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(
                  CustomColors.firebaseOrange,
                ),
              ),
            ) ,
              
  }
}

我已经尝试在 customFormField 中使用 onChange,但我仍然没有在最后一个带有标签总计的 CustomFormField 中或在其下方的文本小部件中更改值。

【问题讨论】:

    标签: flutter textfield onchange textformfield


    【解决方案1】:

    使用TextEditingController

    这里是工作演示:

    import 'package:flutter/material.dart';
    
    const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData.dark().copyWith(
            scaffoldBackgroundColor: darkBlue,
          ),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
              // value "passed" from other screen
              child: MyWidget(price: 12),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatelessWidget {
      double price;
      MyWidget({required this.price}) {
        controllerPrice.text = this.price.toString();
      }
      // price "from other screen"
      TextEditingController controllerPrice = TextEditingController();
      // controller to update Total value
      TextEditingController controllerTotal = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return Column(children: [
          Text("Quantity:"),
          TextField(onChanged: (String t) {
            controllerTotal.text =
                (double.parse(t) * double.parse(controllerPrice.text)).toString();
          }),
          Text("Price:"),
          TextField(readOnly: true, controller: controllerPrice),
          Text("Total:"),
          TextField(readOnly: true, controller: controllerTotal),
        ]);
      }
    }
    

    }

    还有飞镖盘: https://dartpad.dev/?id=051b6df715ecfa9b54e5a771c3927057&null_safety=true

    当然,当您从 Quantity 字段中删除所有内容时,您需要处理输入。

    【讨论】:

      猜你喜欢
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 2021-10-14
      • 2014-07-30
      • 2019-08-12
      • 2020-08-01
      相关资源
      最近更新 更多