![]() Introducing the `forceErrorText` property to both `FormField` and `TextFormField`. With this addition, we gain the capability to trigger an error state and provide an error message without invoking the `validator` method. While the idea of making the `Validator` method work asynchronously may be appealing, it could introduce significant complexity to our current form field implementation. Additionally, this approach might not be suitable for all developers, as discussed by @justinmc in this [comment](https://github.com/flutter/flutter/issues/56414#issuecomment-624960263). This PR try to address this issue by adding `forceErrorText` property allowing us to force the error to the `FormField` or `TextFormField` at our own base making it possible to preform some async operations without the need for any hacks while keep the ability to check for errors if we call `formKey.currentState!.validate()`. Here is an example: <details> <summary>Code Example</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp( const MaterialApp(home: MyHomePage()), ); } class MyHomePage extends StatefulWidget { const MyHomePage({ super.key, }); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final key = GlobalKey<FormState>(); String? forcedErrorText; Future<void> handleValidation() async { // simulate some async work.. await Future.delayed(const Duration(seconds: 3)); setState(() { forcedErrorText = 'this username is not available.'; }); // wait for build to run and then check. // // this is not required though, as the error would already be showing. WidgetsBinding.instance.addPostFrameCallback((_) { print(key.currentState!.validate()); }); } @override Widget build(BuildContext context) { print('build'); return Scaffold( floatingActionButton: FloatingActionButton(onPressed: handleValidation), body: Form( key: key, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: TextFormField( forceErrorText: forcedErrorText, ), ), ], ), ), ), ); } } ``` </details> Related to #9688 & #56414. Happy to hear your thoughts on this. |
||
---|---|---|
.. | ||
api | ||
flutter_view | ||
hello_world | ||
image_list | ||
layers | ||
platform_channel | ||
platform_channel_swift | ||
platform_view | ||
splash | ||
texture | ||
.clang-format | ||
flutter_gallery.readme | ||
README.md |
Flutter Examples
This directory contains several examples of using Flutter. To run an example,
use flutter run
inside that example's directory. See the getting started
guide to install the flutter
tool.
For additional samples, see the
flutter/samples
repo.
Available examples include:
-
Hello, world The hello world app is a minimal Flutter app that shows the text "Hello, world!"
-
Flutter gallery The flutter gallery app no longer lives in this repo. Please see the gallery repo.
-
Layers The layers vignettes show how to use the various layers in the Flutter framework. For details, see the layers README.
-
Platform Channel The platform channel app demonstrates how to connect a Flutter app to platform-specific APIs. For documentation, see https://flutter.dev/platform-channels/.
-
Platform Channel Swift The platform channel swift app is the same as platform channel but the iOS version is in Swift and there is no Android version.
Notes
Note on Gradle wrapper files in .gitignore
:
Gradle wrapper files should normally be checked into source control. The example projects don't do that to avoid having several copies of the wrapper binary in the Flutter repo. Instead, the Gradle wrapper is injected by Flutter tooling, and the wrapper files are .gitignore'd to avoid making the Flutter repository dirty as a side effect of running the examples.