I hope you can help me, i’ve been doing everything but nothing works for me, I have a ListView Builder widget, that lets me add any items I want, each item has 3 fields, one of them is giving me trouble, everytime i type something in hoursController, the cursor goes to the position 0, so is uncomfortable to type, as it should be a numeric value. Here I add part of my code:
void updateTotalHours() {
int newTotal = 0;
for (var project in projects) {
if (project['hours'] != null && project['hours'].isNotEmpty) {
newTotal += int.parse(project['hours']);
}
}
setState(() {
totalHours = newTotal;
});
}
Here’s where I call the widget:
ListView.builder(
shrinkWrap: true,
itemCount: projects.length,
itemBuilder: (context, index) {
return buildProjectItem(index);
},
),
SizedBox(height: 10),
ElevatedButton(
onPressed: () {
setState(() {
projects.add({});
});
},
child: Text('AGREGAR ACTIVIDAD'),
),
Widget buildProjectItem(int index) {
TextEditingController projectController = TextEditingController(text: projects[index]['projectName'] ?? '');
TextEditingController activityController = TextEditingController(text: projects[index]['activityName'] ?? '');
TextEditingController hoursController = TextEditingController(text: projects[index]['hours'] ?? '');
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: TypeAheadFormField<Parametro>(
textFieldConfiguration: TextFieldConfiguration(
controller: projectController,
decoration: InputDecoration(
hintText: 'PROYECTO',
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
),
suggestionsCallback: getSugProjects,
onSuggestionSelected: (project) {
setState(() {
projects[index]['project'] = project.id;
projects[index]['projectName'] = project.name;
projectController.text = project.name;
});
},
autovalidateMode: AutovalidateMode.always,
validator: (proyecto) {
if (proyecto!.isEmpty || !projectsList.any((project) => project.name == proyecto)) {
return 'SELECCIONE UN PROYECTO DE LA LISTA';
} else {
return null;
}
},
itemBuilder: (context, project) {
return ListTile(
title: Text(project.name),
);
},
),
),
SizedBox(width: 10),
Expanded(
child: TypeAheadFormField<Parametro>(
textFieldConfiguration: TextFieldConfiguration(
controller: activityController,
decoration: InputDecoration(
hintText: 'ACTIVIDAD',
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
),
suggestionsCallback: getSugActivities,
onSuggestionSelected: (activity) {
setState(() {
projects[index]['activity'] = activity.id;
projects[index]['activityName'] = activity.name;
activityController.text = activity.name;
});
},
autovalidateMode: AutovalidateMode.always,
validator: (activity) {
if (activity!.isEmpty || !activitiesList.any((act) => act.name == activity)) {
return 'SELECCIONE UNA ACTIVIDAD DE LA LISTA';
} else {
return null;
}
},
itemBuilder: (context, activity) {
return ListTile(
title: Text(activity.name),
);
},
),
),
SizedBox(width: 10),
SizedBox(
width: 200,
child: TextFormField(
controller: hoursController,
readOnly: false,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
labelText: 'HORAS DEDICADAS',
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
),
onChanged: (value) {
setState(() {
projects[index]['hours'] = value;
updateTotalHours();
hoursController.value = TextEditingValue(
text: value,
selection: TextSelection.collapsed(offset: value.length),
);
});
},
),
),
SizedBox(height: 10),
IconButton(
onPressed: () {
setState(() {
projects.removeAt(index);
updateTotalHours();
});
},
icon: Icon(Icons.delete_outline, color: Colors.red),
),
],
),
Divider(),
],
);
}
I have tried using selection property, collapsed, saving the position, but nothing worked for me. And I expect my field to have a normal behavior, so I can move the cursor freely and it stays in the last position i left it