有什么方法可以验证底页中的文本字段吗?

is there any way to validate Textfield in bottomsheet?

我想验证底部表单中的文本字段(不是 textFormField),如果文本字段为空,当我按下保存按钮时它应该会显示错误。 我在下面使用了代码,代码的问题是只有当我按下保存按钮并且应该关闭底部表时它才会显示错误,当我打开底部表时它会显示错误。 有什么方法可以在按下保存按钮而不关闭底页时验证文本字段。 提前致谢。

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: AddAddress()));



class AddNotes extends StatefulWidget {
  @override
  AddAddressState createState() => AddAddressState();
}

class AddAddressState extends State<AddAddress> {

  final _text = TextEditingController();
  bool _validate = false;

  @override
  void dispose(){
    _text.dispose();
    super.dispose();
  }

  bottomSheet() {
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        backgroundColor: Colors.transparent,
        builder: (BuildContext context) {
          return Container(
              height: MediaQuery.of(context).size.height * 0.85,
              decoration: new BoxDecoration(
                color: Colors.transparent,
              ),
              child: Container(
                padding: const EdgeInsets.fromLTRB(20, 10, 20, 0),
                decoration: new BoxDecoration(
                    color: Colors.white,
                    borderRadius: new BorderRadius.only(
                        topLeft: const Radius.circular(10.0),
                        topRight: const Radius.circular(10.0))),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [


                    Text("Address",
                        textScaleFactor: 1.3,
                        style: TextStyle(
                            fontSize: 18,
                            fontFamily: 'SFProDisplay',
                            fontWeight: FontWeight.w600,
                            fontStyle: FontStyle.normal,
                            letterSpacing: 0.45),
                        textAlign: TextAlign.center),

                    Container(
                        height: 215,
                        decoration: BoxDecoration(
                          color: Color(0x7feff1f5),
                          borderRadius: BorderRadius.circular(6),
                        ),
                        padding: EdgeInsets.fromLTRB(17, 16, 17, 25),
                        child: new ConstrainedBox(
                          constraints: BoxConstraints(maxHeight: 200.0),
                          child: new Scrollbar(
                            child: new SingleChildScrollView(
                              scrollDirection: Axis.vertical,
                              reverse: true,
                              child: SizedBox(
                                height: 175.0,
                                child: new TextField(

                                  controller: _text,

                                  maxLines: 100,
                                  decoration: InputDecoration(
                                    hintText: "Address",
                                    hintStyle: TextStyle(
                                      color: Color(0x00FFa6a9af),
                                    ),
                                    border: InputBorder.none,

                                    errorText: _validate ? 'Notes can\'t be Empty' : null,

                                  ),
                                  style: TextStyle(
                                    height: 1.4,
                                    fontSize: 16,
                                    color: Colors.black,
                                    fontFamily: 'regular',
                                    letterSpacing: 0.35,
                                    fontWeight: FontWeight.w400,
                                  ),
                                ),
                              ),
                            ),
                          ),
                        )),

                    Container(
                      height: 50,
                      color: Colors.transparent,
                      padding: EdgeInsets.fromLTRB(0, 0, 188, 0),
                      child:ElevatedButton(
                        child: Text('Save'),
                        onPressed: (){
                          setState(() {
                            _text.text.isEmpty ? _validate = true : _validate = false;
                          });
                        },
                        style: ElevatedButton.styleFrom(
                          primary: Colors.redAccent,
                          onPrimary: Colors.white,
                          textStyle: TextStyle(
                            fontFamily: 'regular',
                            fontSize: 16.0,
                          ),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(25.0),
                          ),),
                      ),
                    ),
                  ],
                ),
              ));
        });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.transparent,
        title: Text(
          "",
          style: TextStyle(color: Colors.black87, fontFamily: "regular"),
          textAlign: TextAlign.left,
        ),
        centerTitle: false,
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            bottomSheet();
          },
          child: Text("AddAddress"),
        ),
      ),
    );
  }
}

正如我所检查的那样,这是因为它没有正确重建,所以你必须关闭它然后打开它,这样改变的状态才会生效。

我添加了一个 changeNotifier class 来保持状态并使用提供程序包通知其侦听器你可以看看它:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MaterialApp(home: AddAddress()));


class AddAddress extends StatefulWidget {
  @override
  AddAddressState createState() => AddAddressState();
}

class AddAddressState extends State<AddAddress> {

  

  @override
  void dispose(){
    super.dispose();
  }

  bottomSheet() {
    showModalBottomSheet(
        context: context,
        isScrollControlled: true,
        backgroundColor: Colors.transparent,
        builder: (BuildContext context) {
          return ChangeNotifierProvider(create: (context) => CustomProvider(),child: CustomTextField());
        });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.transparent,
        title: Text(
          "",
          style: TextStyle(color: Colors.black87, fontFamily: "regular"),
          textAlign: TextAlign.left,
        ),
        centerTitle: false,
      ),
      body: Center(
        child: TextButton(
          onPressed: () {
            bottomSheet();
          },
          child: Text("AddAddress"),
        ),
      ),
    );
  }
}

class CustomTextField extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Container(
        height: MediaQuery.of(context).size.height * 0.85,
        decoration: new BoxDecoration(
          color: Colors.transparent,
        ),
        child: Container(
          padding: const EdgeInsets.fromLTRB(20, 10, 20, 0),
          decoration: new BoxDecoration(
              color: Colors.white,
              borderRadius: new BorderRadius.only(
                  topLeft: const Radius.circular(10.0),
                  topRight: const Radius.circular(10.0))),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [


              Text("Address",
                  textScaleFactor: 1.3,
                  style: TextStyle(
                      fontSize: 18,
                      fontFamily: 'SFProDisplay',
                      fontWeight: FontWeight.w600,
                      fontStyle: FontStyle.normal,
                      letterSpacing: 0.45),
                  textAlign: TextAlign.center),

              Container(
                  height: 215,
                  decoration: BoxDecoration(
                    color: Color(0x7feff1f5),
                    borderRadius: BorderRadius.circular(6),
                  ),
                  padding: EdgeInsets.fromLTRB(17, 16, 17, 25),
                  child: new ConstrainedBox(
                    constraints: BoxConstraints(maxHeight: 200.0),
                    child: new Scrollbar(
                      child: new SingleChildScrollView(
                        scrollDirection: Axis.vertical,
                        reverse: true,
                        child: Consumer<CustomProvider>(
                          builder: (context, item, child) => SizedBox(
                            height: 175.0,
                            child: new TextField(

                              controller: Provider.of<CustomProvider>(context, listen: false).text,

                              maxLines: 100,
                              decoration: InputDecoration(
                                hintText: "Address",
                                hintStyle: TextStyle(
                                  color: Color(0x00FFa6a9af),
                                ),
                                border: InputBorder.none,

                                errorText: item.validate ? 'Notes can\'t be Empty' : null,

                              ),
                              style: TextStyle(
                                height: 1.4,
                                fontSize: 16,
                                color: Colors.black,
                                fontFamily: 'regular',
                                letterSpacing: 0.35,
                                fontWeight: FontWeight.w400,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  )),

              Container(
                height: 50,
                color: Colors.transparent,
                padding: EdgeInsets.fromLTRB(0, 0, 188, 0),
                child:ElevatedButton(
                  child: Text('Save'),
                  onPressed: (){
                    Provider.of<CustomProvider>(context, listen: false).checkValidation();
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.redAccent,
                    onPrimary: Colors.white,
                    textStyle: TextStyle(
                      fontFamily: 'regular',
                      fontSize: 16.0,
                    ),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(25.0),
                    ),),
                ),
              ),
            ],
          ),
        ));
  }
}

class CustomProvider extends ChangeNotifier{
  final text = TextEditingController();
  bool validate = false;
  
  void checkValidation(){
    if(text.text.isEmpty){
      validate = true;
    }else{
      validate = false;
    }
    notifyListeners();
  }
}