0
Description
My App consists of two widgets:
- The first (Autocompleteinput) is composed of an autocomplete field (Autocompletetextfield) and a button beside it as shown in the following image:
- When an option is selected and the button pressed, the option is listed in the second component (Substanceslist), according to the image below:
The Autocompletetextfield present in the first widget needs to have the hintText (text with the same functionality as the html "placeholder") dynamic. The hint should be: "Inform the Xº product", in which "X" should be the amount of items listed in the other widget + 1.
The way I get the number of items listed is through a final int variable that is assigned in the constructor of the Autocompleteinput class, called "nextSub".
Problem
The value of "nextSub" is being updated correctly (as items are inserted and removed from the list in the other widget), but its change is not being reflected in the interface, that is, the hintText is always: "Inform the 1st product", regardless of the amount of items listed in the second component.
The correct hint in this print should be "Inform the 3rd product": .
I believe it is a problem related to setState() (was not used to assign the string "hintText"), since the widget Autocompleteinput is statefull, but I’m not sure where to put this method in order for the widget to work properly.
Question
What to do to make the "nextSub" value appear correctly in the Autocompletetextfield hintText?
Main.Dart code (where the Autocompleteinput component is imported):
class _MyHomePageState extends State<MyHomePage> {
final List<SubstanciaAutocompleteOption> _substanciasAutocompleteOptions = new List<SubstanciaAutocompleteOption>();
final List<SubstanciaAutocompleteOption> _substanciasSelecionadas = new List<SubstanciaAutocompleteOption>();
int _nextSub = 1;
void _addSubstanceToList(SubstanciaAutocompleteOption sub) {
setState(() {
_substanciasSelecionadas.add(sub);
_nextSub += 1;
});
}
@override
Widget build(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
final pageBody = SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: mediaQuery.size.height * 0.1,
padding: EdgeInsets.all(10),
child: AutocompleteInput(
options: _substanciasAutocompleteOptions,
submitHandler: _addSubstanceToList,
nextSub: _nextSub,
),
),
...
Code for the Autocompleteinput widget
class AutocompleteInput extends StatefulWidget {
final List<SubstanciaAutocompleteOption> options; //lista de opções para autocomplete
final Function submitHandler; // o que fazer quando clicar no botão
final int nextSub; // quantidade de itens presentes no segundo componente
AutocompleteInput({
this.options,
this.submitHandler,
this.nextSub
});
@override
_AutocompleteInputState createState() => _AutocompleteInputState();
}
class _AutocompleteInputState extends State<AutocompleteInput> {
AutoCompleteTextField searchTextField;
GlobalKey<AutoCompleteTextFieldState<SubstanciaAutocompleteOption>> key = new GlobalKey();
SubstanciaAutocompleteOption selectedOption;
Widget custonListTile(SubstanciaAutocompleteOption option) {
return Card(
elevation: 5,
margin: EdgeInsets.only(
top: 6,
),
child: Container(
padding: EdgeInsets.only(left: 33, top: 5, bottom: 5, right: 5),
height: 45,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
option.descricao.capitalize(),
style: TextStyle(
fontSize: 16,
),
),
if(option.descricao != option.principioAtivo)
Text(
option.descricao.capitalize(),
style: TextStyle(
fontSize: 14,
color: Colors.black45
),
)
],
),
),
);
}
@override
Widget build(BuildContext context) {
print('nextSub: ${widget.nextSub}');
return Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: searchTextField = AutoCompleteTextField<SubstanciaAutocompleteOption> (
itemSubmitted: (item) {
setState(() {
searchTextField.textField.controller.text = item.descricao;
selectedOption = new SubstanciaAutocompleteOption(
subsId: item.subsId,
principioAtivo: item.principioAtivo,
comercialId: item.comercialId,
descricao: item.descricao
);
});
},
key: key,
clearOnSubmit: false,
suggestions: widget.options,
itemBuilder: (context, item) {
SubstanciaAutocompleteOption opAux = new SubstanciaAutocompleteOption(
subsId: item.subsId,
principioAtivo: item.principioAtivo,
descricao: item.descricao,
comercialId: item.comercialId
);
return custonListTile(opAux);
},
itemSorter: (a, b) {
return a.descricao.compareTo(b.descricao);
},
itemFilter: (item, query) {
return item.descricao.toLowerCase().startsWith(query.toLowerCase());
},
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).primaryColor
)
),
hintText: 'Informe o ${widget.nextSub}º produto',
labelText: 'Adicionar Produto à Mistura',
prefixIcon: Icon(Custom.beaker),
),
style: TextStyle(
fontSize: 18,
),
),
),
Container(
height: double.infinity,
margin: EdgeInsets.only(left: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
boxShadow: [
BoxShadow(color: Colors.green, spreadRadius: 1),
],
),
child: IconButton(
color: Colors.white,
icon: Icon(Icons.add),
onPressed: () {
if(selectedOption != null) {
searchTextField.textField.controller.clear();
widget.submitHandler(selectedOption);
selectedOption = null;
}
else {
// TO DO
}
}
),
),
],
);
}
}
Oops beauty? Edita your question and places the images directly in it.
– Matheus Ribeiro
The value of your property
subsIndex
comes from outside the widgetAutocompleteInput
exemplified in the question, so you probably need to increment it in the function passed in thesubmitHandler
, by putting thesetState()
. If possible show us where you are using this widget.– Matheus Ribeiro
@Matheusribeiro , I made the edits, I believe the error is time to assign hintText, must have some correct place to put setState() but I’m not able to identify where
– César Cardoso
I did some tests here, and I could not reproduce the problem (but I did not use the autocomplete), apparently this right your control...
– Matheus Ribeiro
@Matheusribeiro ai that has the problem, the autocomplete being stored in the variable "searchTextField", in which it is not being updated when the button is clicked, has some way to force the widget Autocompletetextfield, within this various "searchTextfield", run the build method again? Since this variable has an assigned value, the hintText is set and as a consequence of this variable does not be updated, the hintText also does not change. I’ve tried putting setState on the onPressed button but n worked: https://prnt.sc/t98r71
– César Cardoso