mirror of
https://github.com/Iconica-Development/flutter_availability.git
synced 2025-05-19 13:13:44 +02:00
fix: close keyboard for break duration when tapping outside inputfield
This commit is contained in:
parent
e37164831b
commit
ae950ce5df
1 changed files with 69 additions and 21 deletions
|
@ -1,4 +1,5 @@
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
|
import "package:flutter/services.dart";
|
||||||
import "package:flutter_availability/src/util/scope.dart";
|
import "package:flutter_availability/src/util/scope.dart";
|
||||||
|
|
||||||
/// An input field for time selection
|
/// An input field for time selection
|
||||||
|
@ -56,7 +57,7 @@ class TimeInputField extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An input field for giving a duration in minutes
|
/// An input field for giving a duration in minutes
|
||||||
class DurationInputField extends StatelessWidget {
|
class DurationInputField extends StatefulWidget {
|
||||||
///
|
///
|
||||||
const DurationInputField({
|
const DurationInputField({
|
||||||
required this.initialValue,
|
required this.initialValue,
|
||||||
|
@ -70,6 +71,51 @@ class DurationInputField extends StatelessWidget {
|
||||||
///
|
///
|
||||||
final void Function(Duration?) onDurationChanged;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
@ -77,16 +123,15 @@ class DurationInputField extends StatelessWidget {
|
||||||
var options = availabilityScope.options;
|
var options = availabilityScope.options;
|
||||||
var translations = options.translations;
|
var translations = options.translations;
|
||||||
|
|
||||||
void onFieldChanged(String value) {
|
return Focus(
|
||||||
var duration = int.tryParse(value);
|
onFocusChange: (hasFocus) {
|
||||||
if (duration != null) {
|
if (hasFocus) {
|
||||||
onDurationChanged(Duration(minutes: duration));
|
_showOverlay(context);
|
||||||
} else {
|
} else {
|
||||||
onDurationChanged(null);
|
_removeOverlay();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
child: TextFormField(
|
||||||
return TextFormField(
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: translations.time,
|
labelText: translations.time,
|
||||||
labelStyle: theme.inputDecorationTheme.hintStyle,
|
labelStyle: theme.inputDecorationTheme.hintStyle,
|
||||||
|
@ -95,10 +140,13 @@ class DurationInputField extends StatelessWidget {
|
||||||
),
|
),
|
||||||
suffixIcon: const Icon(Icons.access_time),
|
suffixIcon: const Icon(Icons.access_time),
|
||||||
),
|
),
|
||||||
initialValue: initialValue?.inMinutes.toString(),
|
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
style: options.textStyles.inputFieldTextStyle,
|
style: options.textStyles.inputFieldTextStyle,
|
||||||
onChanged: onFieldChanged,
|
onChanged: _onFieldChanged,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue