I try to make a separate TextField widget to use repeatedly. Because there is a lot of code that I would otherwise duplicate
And I want to make the cursor jump to the next TextField when there are 2 numbers in onchanged. So I use the value to see whether there are already 2 numbers inputted. And I use context to focus on the next focus node.
It works if I put it in te same widget, but when I extract the widget. It won't work.
Could you please help me?
Is it possible?
import 'package:flutter/material.dart';
import 'package:careapp/widgets/layout/time_input.dart';
class newInput extends StatefulWidget {
const newInput({Key? key}) : super(key: key);
@override
_newInputState createState() => _newInputState();
}
class _newInputState extends State<newInput> {
final hoursController = TextEditingController();
final minutesController = TextEditingController();
final nextFocusNode = FocusNode();
@override
void dispose() {
hoursController.dispose();
minutesController.dispose();
nextFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final focus = FocusScope.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Add input'),
actions: [
IconButton(
onPressed: _addEvent,
icon: Icon(Icons.save),
),
],
),
body: Card(
elevation: 6,
child: Container(
padding: EdgeInsets.only(top: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
//height: 100,
padding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 20,
),
child: Row(
children: [
Container(
child: Text('Time:'),
),
timeInput(
labelText: 'Hour',
onSubmitted: () {},
controller: hoursController,
onChanged: (value) {
if (value.length == 2)
focus.requestFocus(nextFocusNode);
},
//textInputAction: TextInputAction.next,
// onEditingComplete: () => focus.nextFocus(),
),
Container(
child: Text(
':',
style: TextStyle(
fontSize: 20,
//fontWeight: FontWeight.bold,
),
),
),
timeInput(
labelText: 'Min',
onSubmitted: () {},
controller: minutesController,
focusNode: nextFocusNode,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {},
child: Text('Add Event'),
),
],
)
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
class timeInput extends StatelessWidget {
final String labelText;
final VoidCallback onSubmitted;
final Function? onChanged;
final VoidCallback? onEditingComplete;
FocusNode? focusNode;
final TextInputAction textInputAction;
final TextEditingController controller;
// final String lastname;
// final String birthday;
// final String id;
timeInput(
{required this.labelText,
required this.onSubmitted,
this.focusNode,
this.textInputAction = TextInputAction.done,
this.onChanged,
this.onEditingComplete = _onEditingComplete,
required this.controller});
static _onEditingComplete() {}
@override
Widget build(BuildContext context) {
return Flexible(
child: Container(
padding: EdgeInsets.all(10),
height: 50,
width: 70,
child: TextField(
// onChanged: (_) => onChanged!(),
onChanged: (_) => onChanged!(),
textInputAction: textInputAction,
// onEditingComplete: onEditingComplete,
maxLength: 2,
//style: ,
decoration: InputDecoration(
//labelText: 'Uur',
labelText: labelText,
border: OutlineInputBorder(),
counterText: '',
),
controller: controller,
keyboardType: TextInputType.numberWithOptions(decimal: false),
onSubmitted: (_) =>
onSubmitted(), //You must add an input but underscore indicates that you are not using it
// onChanged: (val) => amountInput = val,
),
),
);
}
}
CodePudding user response:
please try this
import 'package:flutter/material.dart';
import 'package:careapp/widgets/layout/time_input.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
class newInput extends StatefulWidget {
const newInput({Key? key}) : super(key: key);
@override
_newInputState createState() => _newInputState();
}
class _newInputState extends State<newInput> {
final hoursController = TextEditingController();
final minutesController = TextEditingController();
final nextFocusNode = FocusNode();
@override
void dispose() {
hoursController.dispose();
minutesController.dispose();
nextFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final focus = FocusScope.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Add input'),
actions: [
IconButton(
onPressed: (){
},
icon: Icon(Icons.save),
),
],
),
body: Card(
elevation: 6,
child: Container(
padding: EdgeInsets.only(top: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
//height: 100,
padding: EdgeInsets.symmetric(
horizontal: 15,
vertical: 20,
),
child: Row(
children: [
Container(
child: Text('Time:'),
),
timeInput(
labelText: 'Hour',
onSubmitted: () {},
controller: hoursController,
onChanged: (v) {
if (v.length == 2){
print("ok");
FocusScope.of(context).nextFocus();
}
//focus.requestFocus(nextFocusNode);
},
//textInputAction: TextInputAction.next,
),
Container(
child: Text(':',
style: TextStyle(
fontSize: 20,
//fontWeight: FontWeight.bold,
),
),
),
timeInput(
labelText: 'Min',
onSubmitted: () {},
controller: minutesController,
focusNode: nextFocusNode,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {},
child: Text('Add Event'),
),
],
)
],
),
),
]),
)
)
);
}
}
class timeInput extends StatelessWidget {
final String labelText;
final VoidCallback onSubmitted;
final Function? onChanged;
final VoidCallback? onEditingComplete;
FocusNode? focusNode;
final TextInputAction textInputAction;
final TextEditingController controller;
// final String lastname;
// final String birthday;
// final String id;
timeInput(
{required this.labelText,
required this.onSubmitted,
this.focusNode,
this.textInputAction = TextInputAction.done,
this.onChanged,
this.onEditingComplete = _onEditingComplete,
required this.controller});
static _onEditingComplete() {}
@override
Widget build(BuildContext context) {
return Flexible(
child: Container(
padding: EdgeInsets.all(10),
height: 50,
width: 70,
child: TextField(
// onChanged: (_) => onChanged!(),
onChanged: (v)=>onChanged!(v),
textInputAction: textInputAction,
// onEditingComplete: onEditingComplete,
maxLength: 2,
//style: ,
decoration: InputDecoration(
//labelText: 'Uur',
labelText: labelText,
border: OutlineInputBorder(),
counterText: '',
),
controller: controller,
keyboardType: TextInputType.numberWithOptions(decimal: false),
onSubmitted: (_) =>
onSubmitted(), //You must add an input but underscore indicates that you are not using it
// onChanged: (val) => amountInput = val,
),
),
);
}
}