import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
final RouteObserver<ModalRoute> routeObserver = RouteObserver<ModalRoute>();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorObservers: [routeObserver],
home: FormScreen(),
);
}
}
class FormScreen extends StatefulWidget {
const FormScreen({super.key});
@override
State<FormScreen> createState() => _FormScreenState();
}
class _FormScreenState extends State<FormScreen> {
@override
Widget build(BuildContext context) {
// final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Form Builder Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: FormChild(),
),
),
);
}
}
class FormChild extends StatefulWidget {
const FormChild({super.key});
@override
State<FormChild> createState() => _FormChildState();
}
class _FormChildState extends State<FormChild> with ScopedGetItMixin {
final GlobalKey<FormBuilderState> _formBuilderKey = GlobalKey<FormBuilderState>();
AutovalidateMode _autovalidateMode = AutovalidateMode.disabled;
@override
Widget build(BuildContext context) {
return FormBuilder(
key: _formBuilderKey,
autovalidateMode: _autovalidateMode,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
spacing: 10.0,
children: [
// Submit button
ElevatedButton(
style: ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)))),
onPressed: () {
FocusManager.instance.primaryFocus?.unfocus();
},
child: const Text('Unfocus'),
),
ElevatedButton(
style: ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)))),
onPressed: () {
final result = _formBuilderKey.currentState?.saveAndValidate();
if(result != true && _autovalidateMode != AutovalidateMode.onUserInteraction){
setState(() {
_autovalidateMode = AutovalidateMode.onUserInteraction;
});
}
},
child: const Text('submit'),
),
ElevatedButton(
style: ButtonStyle(shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)))),
onPressed: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
showDragHandle: true,
builder: (context) {
return SizedBox(
height: 500,
width: 400,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FormBuilderTextField(
name: 'textfield2',
decoration: const InputDecoration(
labelText: 'Enter text 1',
),
validator: FormBuilderValidators.required(),
)
],
),
);
},
);
},
child: Text("Open bottom sheet"),
),
],
),
),
// TextField 1
FormBuilderTextField(
name: 'textfield1',
decoration: const InputDecoration(
labelText: 'Enter text 1',
),
validator: FormBuilderValidators.required(),
),
const SizedBox(height: 20),
],
),
);
}
}
mixin ScopedGetItMixin<T extends StatefulWidget> on State<T> implements RouteAware {
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(this, ModalRoute.of(context)!);
}
@override
void dispose() {
super.dispose();
routeObserver.unsubscribe(this);
}
@override
void didPop() {
}
@override
void didPopNext() {
}
@override
void didPush() {
}
@override
void didPushNext() {
}
}
Is there an existing issue for this?
Package/Plugin version
10.0.0-dev.1
Platforms
Flutter doctor
Flutter doctor
Minimal code example
Code sample
Current Behavior
I've developed a mixin called ScopedGetItMixin for use with StatefulWidget that contains a FormBuilder. However, I've noticed that after the form calls saveAndValidate, tapping a button to open a showModalBottomSheet causes a FormBuilderTextField to unexpectedly regain focus, triggering the keyboard to appear.
The main cause might be ScopedGetItMixin, but at the moment, I’m not sure why using ScopedGetItMixin results in this behavior.
Expected Behavior
I hope the focus behavior of FormBuilderTextField gets fixed.
Steps To Reproduce
I will describe it again through the video below.
focus_textfield1.mp4
Aditional information
No response