fix: close keyboard for break duration when tapping outside inputfield

This commit is contained in:
Freek van de Ven 2024-07-25 07:35:16 +02:00 committed by Bart Ribbers
parent e37164831b
commit ae950ce5df

View file

@ -1,4 +1,5 @@
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:flutter_availability/src/util/scope.dart";
/// An input field for time selection
@ -56,7 +57,7 @@ class TimeInputField extends StatelessWidget {
}
/// An input field for giving a duration in minutes
class DurationInputField extends StatelessWidget {
class DurationInputField extends StatefulWidget {
///
const DurationInputField({
required this.initialValue,
@ -70,6 +71,51 @@ class DurationInputField extends StatelessWidget {
///
final void Function(Duration?) onDurationChanged;
@override
State<StatefulWidget> createState() => _DurationInputFieldState();
}
class _DurationInputFieldState extends State<DurationInputField> {
OverlayEntry? _overlayEntry;
@override
void dispose() {
_removeOverlay();
super.dispose();
}
void _onFieldChanged(String value) {
var duration = int.tryParse(value);
if (duration != null) {
widget.onDurationChanged(Duration(minutes: duration));
} else {
widget.onDurationChanged(null);
}
}
void _showOverlay(BuildContext context) {
_overlayEntry = _createOverlayEntry(context);
Overlay.of(context).insert(_overlayEntry!);
}
void _removeOverlay() {
_overlayEntry?.remove();
_overlayEntry = null;
}
OverlayEntry _createOverlayEntry(BuildContext context) => OverlayEntry(
builder: (context) => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
_removeOverlay();
},
behavior: HitTestBehavior.translucent,
child: Container(
color: Colors.transparent,
),
),
);
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
@ -77,16 +123,15 @@ class DurationInputField extends StatelessWidget {
var options = availabilityScope.options;
var translations = options.translations;
void onFieldChanged(String value) {
var duration = int.tryParse(value);
if (duration != null) {
onDurationChanged(Duration(minutes: duration));
return Focus(
onFocusChange: (hasFocus) {
if (hasFocus) {
_showOverlay(context);
} else {
onDurationChanged(null);
_removeOverlay();
}
}
return TextFormField(
},
child: TextFormField(
decoration: InputDecoration(
labelText: translations.time,
labelStyle: theme.inputDecorationTheme.hintStyle,
@ -95,10 +140,13 @@ class DurationInputField extends StatelessWidget {
),
suffixIcon: const Icon(Icons.access_time),
),
initialValue: initialValue?.inMinutes.toString(),
keyboardType: TextInputType.number,
style: options.textStyles.inputFieldTextStyle,
onChanged: onFieldChanged,
onChanged: _onFieldChanged,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
),
);
}
}