Open danielweil opened 3 years ago
@awhitford mind taking this one?
Maybe not a frequent request, and I guess it's pretty easy to override.. and this issue is quite old. However, having a default option to edit the entry, in addition to touch / spin would be really nice.
Would be nice to have this feature
If the middle
Text
widget was replaced with aTextField
then the keyboard should become visible.
And if use onChanged
in TextField widget will be recreated every time the value changes, which means that the cursor and selection will be reset.
I ended up updating value only on onEditingComplete
, onSubmitted
and onTapOutside
, but haven't properly tested it yet in all situations.
My modified version look like this:
class TouchSpin extends StatefulWidget {
final num value;
final num min;
final num max;
final num step;
final double iconSize;
final ValueChanged<num>? onChanged;
final NumberFormat? displayFormat;
final Icon subtractIcon;
final Icon addIcon;
final EdgeInsetsGeometry iconPadding;
final TextStyle? textStyle;
final Color? iconActiveColor;
final Color? iconDisabledColor;
final bool enabled;
const TouchSpin({
Key? key,
this.value = 1.0,
this.onChanged,
this.min = 1.0,
this.max = 9999999.0,
this.step = 1.0,
this.iconSize = 24.0,
this.displayFormat,
this.subtractIcon = const Icon(Icons.remove),
this.addIcon = const Icon(Icons.add),
this.iconPadding = const EdgeInsets.all(0),
this.textStyle,
this.iconActiveColor,
this.iconDisabledColor,
this.enabled = true,
}) : super(key: key);
@override
TouchSpinState createState() => TouchSpinState();
}
class TouchSpinState extends State<TouchSpin> {
late num _value;
final TextEditingController _controller = TextEditingController();
bool get minusBtnDisabled =>
_value <= widget.min ||
_value - widget.step < widget.min ||
!widget.enabled;
bool get addBtnDisabled =>
_value >= widget.max ||
_value + widget.step > widget.max ||
!widget.enabled;
@override
void initState() {
super.initState();
_value = widget.value;
_controller.text = _value.toString();
}
@override
void didUpdateWidget(TouchSpin oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.value != widget.value) {
setState(() {
_value = widget.value;
_controller.text = _value.toString();
});
widget.onChanged?.call(widget.value);
}
}
Color? _spinButtonColor(bool btnDisabled) => btnDisabled
? widget.iconDisabledColor ?? Theme.of(context).disabledColor
: widget.iconActiveColor ?? Theme.of(context).textTheme.labelLarge?.color;
void _adjustValue(num adjustment) {
num newVal = _value + adjustment;
setState(() {
_value = newVal;
_controller.text = _value.toString();
});
widget.onChanged?.call(newVal);
}
void _onTextChanged() {
final newValue = _controller.text.isEmpty
? widget.min
: num.tryParse(_controller.text) ?? widget.min;
print(newValue);
if (newValue != _value &&
newValue >= widget.min &&
newValue <= widget.max) {
setState(() {
_value = newValue;
});
widget.onChanged?.call(newValue);
} else {
_controller.text = _value.toString();
}
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
IconButton(
padding: widget.iconPadding,
iconSize: widget.iconSize,
color: _spinButtonColor(minusBtnDisabled),
icon: widget.subtractIcon,
onPressed: minusBtnDisabled ? null : () => _adjustValue(-widget.step),
),
SizedBox(
width: 50,
child: TextField(
decoration: null,
controller: _controller,
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
textAlign: TextAlign.center,
style: widget.textStyle,
onEditingComplete: () => _onTextChanged(),
onSubmitted: (_) => _onTextChanged(),
onTapOutside: (_) => _onTextChanged(),
),
),
IconButton(
padding: widget.iconPadding,
iconSize: widget.iconSize,
color: _spinButtonColor(addBtnDisabled),
icon: widget.addIcon,
onPressed: addBtnDisabled ? null : () => _adjustValue(widget.step),
),
],
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
Is there a way to include a numeric keyboard when touching the field in the middle? If I still want to use the spinner but I have to type a big number.
Thanks! Love your package!