首页 > 解决方案 > 即使在插入值后文本字段仍显示错误消息

问题描述

我在下面的代码中使用了 3 个文本字段,我已经验证了每条消息,当我单击凸起的按钮时它会显示错误消息,但是之后当我输入值时,它仍然会在屏幕上显示相同的错误消息有人可以请帮我。

这是我的代码:

   import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:toast/toast.dart';

class AddPromo extends StatefulWidget {
  @override
  _AddPromoState createState() => _AddPromoState();
}

class _AddPromoState extends State<AddPromo> {
  final databaseReference = Firestore.instance;

  var priceReductionController = TextEditingController();
  var perReductionController = TextEditingController();
  var promocodeController = TextEditingController();

  bool _validate = false;
  bool _validatePrice = false;
  bool _validatePerReduction = false;
  bool _validatePromoCode = false;


  @override
  void dispose() {
    priceReductionController.dispose();
    perReductionController.dispose();
    promocodeController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Add promo"),backgroundColor: Colors.indigo,),
      body: Column(
        children : <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              keyboardType: TextInputType.number,
            controller: priceReductionController,
              decoration: InputDecoration(labelText: "Price Reduction",
                  errorText: _validatePrice ? 'value cant be empty' : null,
                  border: new OutlineInputBorder(
                borderRadius: const BorderRadius.all(
                  const Radius.circular(0.0),
                ),
                borderSide: new BorderSide(
                  color: Colors.indigo,
                  width: 1.0,
                ),
              )),
            ),
          ),
         Padding(
           padding: const EdgeInsets.all(8.0),
           child: TextField(
             keyboardType: TextInputType.number,


             controller: perReductionController,
             decoration: new InputDecoration(labelText: "Percentage Reduction",
                 errorText: _validatePerReduction ? 'value cant be empty' : null,
                 border: new  OutlineInputBorder(
               borderSide: new BorderSide(color: Colors.indigo)

             )),


            ),
         ),
         Padding(
           padding: const EdgeInsets.all(8.0),
           child: TextField(

             controller: promocodeController,
             decoration: InputDecoration(labelText: "Promo code",
                 errorText: _validatePromoCode ? 'value cant be empty' : null,
                 border: OutlineInputBorder(

             )),

            ),
         ),
          Spacer(flex:2),
        Container(
          width: 350,

          child: RaisedButton(
            color: Colors.indigo,
            onPressed: () async {

              //perform the validation first
              setState(() {
                priceReductionController.text.isEmpty
                    ? _validatePrice = true
                    : _validatePrice = false;
                perReductionController.text.isEmpty
                    ? _validatePerReduction = true
                    : _validatePerReduction = false;
                promocodeController.text.isEmpty
                    ? _validatePromoCode = true
                    : _validatePromoCode = false;
              });

              //verify that all are fine
              if (_validatePrice || _validatePromoCode || _validatePerReduction) {
                return;
              }

              //store the values into the database
              DocumentReference ref = await databaseReference.collection("promo_codes")
                  .add({
                'percentage_reduction': perReductionController.text,
                'price_reduction': priceReductionController.text,
                'promo_code': promocodeController.text,
              });

              Scaffold.of(context)
                  .showSnackBar(SnackBar(content: Text("Promo saved.")))
                  .closed
                  .then((reason) {
                // snackbar is now closed
              });

这就是我的代码在我点击按钮时没有输入任何字段时的样子,后来我用这些值填充了它
//打印(ref.documentID); },

数据正在存储在数据库中,但错误消息仍然没有从屏幕上消失

I/OpenGLRenderer( 6519): Initialized EGL, version 1.4
D/OpenGLRenderer( 6519): Swap behavior 2
W/IInputConnectionWrapper( 6519): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 6519): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper( 6519): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper( 6519): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper( 6519): endBatchEdit on inactive InputConnection
W/BiChannelGoogleApi( 6519): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzak@172de21
W/DynamiteModule( 6519): Local module descriptor class for com.google.firebase.auth not found.
I/FirebaseAuth( 6519): [FirebaseAuth:] Loading module via FirebaseOptions.
I/FirebaseAuth( 6519): [FirebaseAuth:] Preparing to create service connection to gms implementation
D/FirebaseAuth( 6519): Notifying id token listeners about user ( 7pkcfF4j1yVLCnMUn9BE0uvjL2s1 ).
I/flutter ( 6519): AsyncSnapshot<String>(ConnectionState.waiting, null, null)
W/DynamiteModule( 6519): Local module descriptor class for providerinstaller not found.
I/DynamiteModule( 6519): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller( 6519): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
I/dminbookingpag( 6519): The ClassLoaderContext is a special shared library.
I/chatty  ( 6519): uid=10296(m20zero.adminbookingpage) AsyncTask #2 identical 1 line
I/dminbookingpag( 6519): The ClassLoaderContext is a special shared library.
V/NativeCrypto( 6519): Registering com/google/android/gms/org/conscrypt/NativeCrypto's 286 native methods...
W/dminbookingpag( 6519): Accessing hidden field Ljava/nio/Buffer;->address:J (light greylist, reflection)
W/dminbookingpag( 6519): Accessing hidden method Ljava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String; (light greylist, reflection)
D/NetworkSecurityConfig( 6519): No Network Security Config specified, using platform default
I/ProviderInstaller( 6519): Installed default security provider GmsCore_OpenSSL
W/dminbookingpag( 6519): Accessing hidden field Ljava/net/Socket;->impl:Ljava/net/SocketImpl; (light greylist, reflection)
W/dminbookingpag( 6519): Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (light greylist, linking)
W/dminbookingpag( 6519): Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (light greylist, linking)
W/dminbookingpag( 6519): Accessing hidden field Ljava/io/FileDescriptor;->descriptor:I (light greylist, JNI)
W/dminbookingpag( 6519): Accessing hidden method Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V (light greylist, reflection)
W/dminbookingpag( 6519): Accessing hidden method Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy; (light greylist, linking)
W/dminbookingpag( 6519): Accessing hidden method Ldalvik/system/BlockGuard$Policy;->onNetwork()V (light greylist, linking)
I/flutter ( 6519): 21
I/flutter ( 6519): AsyncSnapshot<String>(ConnectionState.done, 21, null)
W/IInputConnectionWrapper( 6519): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 6519): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper( 6519): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper( 6519): requestCursorAnchorInfo on inactive InputConnection
E/flutter ( 6519): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Scaffold.of() called with a context that does not contain a Scaffold.
E/flutter ( 6519): No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.
E/flutter ( 6519): There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
E/flutter ( 6519):   https://api.flutter.dev/flutter/material/Scaffold/of.html
E/flutter ( 6519): A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().
E/flutter ( 6519): A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
E/flutter ( 6519): The context used was:
E/flutter ( 6519):   AddPromo
E/flutter ( 6519): #0      Scaffold.of (package:flutter/src/material/scaffold.dart:1316:5)
E/flutter ( 6519): #1      _AddPromoState.build.<anonymous closure> (package:adminbookingpage/screens/addPromo.dart:119:24)
E/flutter ( 6519): <asynchronous suspension>
E/flutter ( 6519): #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
E/flutter ( 6519): #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
E/flutter ( 6519): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter ( 6519): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter ( 6519): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter ( 6519): #7      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
E/flutter ( 6519): #8      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
E/flutter ( 6519): #9      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter ( 6519): #10     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
E/flutter ( 6519): #11     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter ( 6519): #12     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
E/flutter ( 6519): #13     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
E/flutter ( 6519): #14     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter ( 6519): #15     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter ( 6519): #16     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter ( 6519): #17     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter ( 6519): #18     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter ( 6519): #19     _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter ( 6519): #20     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter ( 6519): #21     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter ( 6519): #22     _invoke1 (dart:ui/hooks.dart:273:10)
E/flutter ( 6519): #23     _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)

标签: firebasevalidationflutterdart

解决方案


Blockquote Form(key: _formKey,autovalidateMode: AutovalidateMode.onUserInteraction)

您应该将Autovalidate Mode.onUserInteraction属性添加到表单小部件中,这样您就可以在每次用户更改某些值时验证表单。


推荐阅读