You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter跨页面表单验证遇Null错误,求可行解决方案

Flutter跨组件表单验证与Null错误解决

问题场景

在Flutter中实现表单验证时,需要在独立的按钮组件中触发主页面表单的验证操作,点击按钮时出现Null错误,错误截图如下:
错误截图

相关代码如下:

主文件代码

import 'package:flutter/material.dart';
import 'package:intl_flutter_deneme/buton.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
import 'package:share_plus/share_plus.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.amber),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController phoneController = TextEditingController();
  bool isButtonActive = false;
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('phone number settings'),
      ),
      body: Center(
        child: Column(
          children: [
            Form(
              key: _formKey,
              child: InternationalPhoneNumberInput(
                countries: ['TR'],
                onInputChanged: (PhoneNumber number) {
                  print(number.phoneNumber);
                },
                maxLength: 13,
                hintText: '5## ### ## ##',
                validator: (deger) {
                  if(deger!.isEmpty && deger.length < 13) {
                    return 'doğru şekilde numara gir';
                  }return null;
                },
                spaceBetweenSelectorAndTextField: 0,
                inputDecoration: InputDecoration(),
                textFieldController: phoneController,
              ),
            ),
            ButonIslemi(),
                
            ElevatedButton(
                onPressed: sharedMessage, child: Text('share')),
          ],
        ),
      ),
    );
  }

  void sharedMessage() {
    String message = 'https://www.instagram.com/atakansever_/';
    Share.share(message);
  }
}

按钮验证组件代码

import 'package:flutter/material.dart';
import 'package:intl_flutter_deneme/main.dart';

class ButonIslemi extends StatelessWidget {
  ButonIslemi({super.key});
  final formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(onPressed: () {
      if(formKey.currentState!.validate()) {
        print('işlem başarılı');
      }
    }, child: Text('bas'));
  }
}

错误原因

  1. Key不匹配:按钮组件中新建的formKey是独立的GlobalKey,没有和主页面Form组件绑定的_formKey关联,导致formKey.currentState为null,使用!强制解包时触发Null错误。
  2. Validator逻辑错误:原验证条件deger!.isEmpty && deger.length <13逻辑矛盾,空字符串的length为0,该条件永远无法触发,无法正确验证输入。

解决方案

1. 传递FormKey到按钮组件

将主页面的_formKey作为参数传递给按钮组件,让按钮使用真实绑定到Form的Key执行验证。

2. 修正Validator逻辑

调整验证条件,确保能正确判断空输入和长度不足的情况。

修正后的代码

主文件代码

import 'package:flutter/material.dart';
import 'package:intl_flutter_deneme/buton.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
import 'package:share_plus/share_plus.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.amber),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController phoneController = TextEditingController();
  bool isButtonActive = false;
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('phone number settings'),
      ),
      body: Center(
        child: Column(
          children: [
            Form(
              key: _formKey,
              child: InternationalPhoneNumberInput(
                countries: ['TR'],
                onInputChanged: (PhoneNumber number) {
                  print(number.phoneNumber);
                },
                maxLength: 13,
                hintText: '5## ### ## ##',
                validator: (deger) {
                  // 修正验证逻辑:判断空值或长度不足
                  if (deger == null || deger.isEmpty || deger.length < 13) {
                    return 'doğru şekilde numara gir';
                  }
                  return null;
                },
                spaceBetweenSelectorAndTextField: 0,
                inputDecoration: InputDecoration(),
                textFieldController: phoneController,
              ),
            ),
            // 将_formKey传递给按钮组件
            ButonIslemi(formKey: _formKey),
                
            ElevatedButton(
                onPressed: sharedMessage, child: Text('share')),
          ],
        ),
      ),
    );
  }

  void sharedMessage() {
    String message = 'https://www.instagram.com/atakansever_/';
    Share.share(message);
  }
}

按钮验证组件代码

import 'package:flutter/material.dart';

class ButonIslemi extends StatelessWidget {
  // 接收外部传递的formKey
  final GlobalKey<FormState> formKey;
  
  const ButonIslemi({super.key, required this.formKey});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(onPressed: () {
      // 先判断currentState是否不为null,再执行验证
      if (formKey.currentState != null && formKey.currentState!.validate()) {
        print('işlem başarılı');
      }
    }, child: Text('bas'));
  }
}

内容的提问来源于stack exchange,提问作者Atakan Sever

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 06:04:57