Dropdown box not displaying selected value - flutter

When I select a value from my dropdown the hint text does not change:
String fontSizeValue;
new DropdownButton<String>(
items: new List<double>.generate(72, (i) => i + 2.0).map((double value) {
return new DropdownMenuItem<String>(
value: value.toString(),
child: new Text(value.toString()),
);
}).toList(),
onChanged: (String _) {
setState(() {
fontSize = double.parse(_);
fontSizeValue = _;
print(fontSizeValue);
});
},
value: fontSizeValue,
hint: Text('Select'),
)),
],
),
),
);
Any idea how I can get the selected value to show instead of "select"? Thanks

You did not post enough code, but I'll take a wild guess anyway, because there are a lot of questions with this problem:
Your variable String fontSizeValue; is defined locally, probably in the build function.
You have to define it in a wider scope, so it will retain it's value after another call to build that will happen when you call setState. Probably as a class member of your State class.

Related

Reload page after locale change

After changing locale in context.setLocale() language in inactive widgets change. But I cannot figure out, hoe to reload current widget in new locale. Any ideas how to get it working?
Body of widget:
Form(
child: CardSettings(
children: <CardSettingsSection>[
CardSettingsSection(
header: CardSettingsHeader(
label: 'settings.general'.tr(),
),
children: [
CardSettingsListPicker(
label: 'Language',
items: context.supportedLocales
.map((locale) =>
locale.toStringWithSeparator(separator: ' '))
.toList(),
initialItem:
context.locale.toStringWithSeparator(separator: ' '),
onChanged: (String newLocale) {
context.setLocale(newLocale.toLocale(separator: ' '));
_getOptions();
},
),
],
),
CardSettingsSection(
header: CardSettingsHeader(
label: 'Map',
),
children: [
CardSettingsListPicker(
label: 'default floor',
items: _floorList,
initialItem: _floor,
onChanged: (String value) {
var floor = tr('plan.floor.' + value);
_preferences.setString('mapDefaultFloor', floor);
},
),
],
),
],
),
);
And options are loaded via async function called in initState and later on in code...
void _getOptions() {
setState(() {
_floorList = Floor.values
.map((value) => tr('plan.floor.' + value.toString().split('.')[1]))
.toList();
_planTypeList = PlanType.values
.map((value) => tr('plan.type.' + value.toString().split('.')[1]))
.toList();
_floor = tr('plan.floor.' +
(_preferences.getString('mapDefaultFLoor') ?? 'ground'));
_planType = tr('plan.type.' +
(_preferences.getString('mapDefaultType') ?? 'newNumbers'));
});
}
stateful widgets automatically reload when you update their state. therefore, all you need to do is have your widget set as a StatefulWidget, and use the setState function to tell flutter that a change has been made to the state, and the widget needs to reload.
Taken from the flutter project template:
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
in the example showed above, the _counter is updated in the state, and in order for it to show the correct value on the app itself, the setState function is called.
Solution was to make _getOptions() async and add the locale change there with await keyword. This way it is ensured that locale is changed before loading new values...

Flutter DropDownButton value not changing after selecting a new value

I have been trying to make an external UI that a user can use to make certain changes to a database(dynamodb) in the cloud. When I select a new value, I want it to show the change that the user wants to make, without actually changing the database. The changes are saved only when I press a button on the appbar. Also when I use setState to rebuild the button, the value doesn't change on the cloud and it also changes the value for all of the buttons in the column(works fine without a setState). The code that I have provided changes the database when I press the save icon, but the drop-down button value stays the same unless I refresh the page. I apologize if I haven't explained my issue clearly enough, this is my first time posting on Stackoverflow, and I'm still learning about how to work with flutter and aws amplify.
body: InteractiveViewer(
constrained: false,
child: DataTable(
columns: [
DataColumn(label: Text('Apt #')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Availability')),
DataColumn(label: Text('Price')),
DataColumn(label: Text('Area'))
],
rows: aprts.map<DataRow>((element) { //aprts is a list that contains apartment objects.
return DataRow(cells: [
DataCell(Text(element.aptNum.toString())),
DataCell(Text(element.type)),
DataCell(DropdownButton<String>( /// this is the part im having problems wi
value: element.availabily, // gets the value for the availability attribute for the element and stores it into value.
onChanged: (String newValue) {
availValue = newValue; //stores the newValue in a global variable that is used in a function that is used toactually make changes to the database.
tempAvail = element;
},
items: <String>['AVAILABLE', 'SOLD', 'RESERVED']
.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)), // end of problem.
DataCell(TextField(
controller: TextEditingController()
..text = element.price.toString(),
onChanged: (text) {
aptPrice = text;
tempPrice = element;
},
)),
DataCell(TextField(
controller: TextEditingController()..text = element.area,
onChanged: (text) {
aptArea = text;
tempArea = element;
},
)),
]);
}).toList()),
),
What the app looks like. After pressing the button
Use
onChanged: (String newValue) {
setState(() {
availValue = newValue;
tempAvail = element;
}
)
},
because for every change in the UI you must call setState((){})

Create Item list for DropdownButton in Flutter

I'm back with another issue with the DropdownButton.
The DropdownButton is not enabled. I found this in api.flutter.dev
If the onChanged callback is null or the list of items is null then
the dropdown button will be disabled, i.e. its arrow will be displayed
in grey and it will not respond to input.
Here is my code now:
return new DropdownButton<String>(
hint: new Text("Select Agency"),
value: _currentAgency,
onChanged: changedDropDownAgency,
items: snapshot.data.docs.forEach((document) {
return new DropdownMenuItem<String>(
value: document.data()['name'],
child: new Text(document.data()['name']),
);
}),
);
void changedDropDownAgency(String selected_agency) {
setState(() {
_currentAgency = selected_agency;
});
globals.selectedAgency = selected_agency;
}
The forEach loop runs fine and in debug mode I can see that there is data in the document object. I don't know how to debug the DropdownButton code to see why the button is not active. Any suggestions would be helpful.
Thanks.
forEach() on Iterables does not return any value (see: https://api.dart.dev/stable/2.10.5/dart-core/Iterable/forEach.html), and thus items is null and the DropdownButton is disabled. Use map instead (https://api.dart.dev/stable/2.10.5/dart-core/Iterable/map.html). Example:
snapshot.data.docs.map<DropdownMenuItem<String>>((document) {
return new DropdownMenuItem<String>(
value: document.data()['name'],
child: new Text(document.data()['name']),
);
}).toList(),

Group radio button in listView

How to use group button in listView ? In each row, it has two radio button.
The problem now is if I select one of the radio button , the radio button not showing it is selected.
int value;
Map<int, bool> answers = {};
String _radioValue;
String choice;
int count = 0;
...item['questions']
.asMap()
.entries
.map((items) {
count++;
return TableRow(children: [
Padding(
padding: EdgeInsets.all(10),
child: Text(items.value['name'])),
Row(
children: [
Radio(
value: items.value['id'],
groupValue: count,
onChanged: (val) {
setSelectedRadioTile(val);
},
),
Text("Yes"),
Radio(
value: items.value['id'] + count,
groupValue: count,
onChanged: (val) {
setSelectedRadioTile(val);
},
),
Text("N/A")
],
)
]);
}).toList()
setSelectedRadioTile(int val) {
print(val);
setState(() {
count = val;
});
}
Okay well I have built you a working version based on what you provided here. Please keep in mind that it would probably be a good idea to look at the documentation more in-depth so you get a feeling of how some widgets behave and what specific properties (like groupValue) are for. Also keep in mind that the following code is not optimised or whatsoever, I just got it worked out for your case - thinking about how to structure your data overall is some fundamental thing you should take a look at. Maybe try some out some flutter courses which are available or look at some youtube content from known flutter coders. But now back to some code stuff.
I used those properties in my StatefulWidget to work with. Since you use some kind of question map and I don't know how it looks like, I just used something bare bones:
/// Map which has the question ID as its key and the answer from the user (currently true for yes and false for no (or n/a as in your case)
Map<int, bool> _answers = {};
/// Map which holds the information of your questions. Right now only an ID to be able to reference it and the actual question - again very bare bones
Map<String, dynamic> _item = {
'questions': [
{
'id': 0,
'question': 'Is this legit?',
},
{
'id': 1,
'question': 'Oh really?',
},
]
};
Then the method which will be called by the Radio widget once onChanged is triggered:
/// We need to know which question has been answered (therefore the ID) and which (bool) answer has been clicked by the user
_setSelectedRadioTile(int id, bool answer) {
setState(() {
_answers[id] = answer;
});
}
And now the widget part - since your code starts where you iterate over the questions, I also share this part specifically:
/// Since the map itself is typed as <String, dynamic>, accessing 'questions' will return dynamic. Only we, as we know the structure, know that this is indeed a list. Therefore we need to cast this as "List<dynamic>" so we can iterate over it and won't get exceptions
(_item['questions'] as List<dynamic>)
.map(
(question) => TableRow(children: [
Padding(
padding: EdgeInsets.all(10),
child: Text(question['question'])),
Row(
children: [
Radio(
/// The [value] property of Radio tells us, which property is used in [onChanged] - therefore now once this Radio is clicked, true is provided in the [onChanged] callback
value: true,
/// [groupValue] is the value which this Radio is bound to. As you probably know, only one Radio button should be active for a group. So if you have a question which has several possible answers as radio buttons, we only want one of them to be active at a time. Thats what the [groupValue] is for. Since we iterate over all questions and every entity of a question (currently) has two possible answers (Yes and N/A), both those answers are for a specific question - the question with the current ID
groupValue: _answers[question['id']],
onChanged: (answer) {
_setSelectedRadioTile(question['id'], answer);
},
),
Text("Yes"),
Radio(
value: false,
groupValue: _answers[question['id']],
onChanged: (answer) {
_setSelectedRadioTile(question['id'], answer);
},
),
Text("N/A")
],
)
]),
)
.toList(),
This should work on your side once you updated this example to fit with your data model. Again: I advise you to think about how you structure your data generally.

How can I create a conditional sentence for each key in a DropDownMenu map?

I know this can be hella standard for most of you guys, but I'm pretty new with Dart and I'm having trouble to find out a way to create a if-else statement for each key in this map I made.
This '_ramoAtividade' holds the key/value for a DropDownMenu, where the user select an item. As you can observe, each key holds a specific double value, and I want to set a exclusive if-else statement depending on the calculations I get by this function.
If the user choose "Industrial" in the DropDownMenu, and the calculation of 'debCalc' return less than the "Industrial" value (2.5), then it should return "User not allowed to promotion", but if the result of 'debCalc' is more than the selected item in the DropDownMenu, then it returns "User allowed to promotion".
To get the list of DropdownMenuItems for a Map<String, dynamic> map = {somedata} dynamically, use:
List<DropdownMenuItem>[
for(final String key in map.keys) DropdownMenuItem(
value: map[key],
child: Text(key),
);
]
Your onChanged function:
onChanged: (double newValue) {
// do the necessary calculations with your value
},
final code for your button:
DropdownButton<double>(
onChanged: (double newValue) {
// do the necessary calculations with your value
debCalc(newValue);
},
items: <DropdownMenuItem<double>>[
for(final String key in _ramoAtividade.keys) DropdownMenuItem<double>(
value: map[key],
child: Text(key),
);
],
),