I am developing a form with 11 multiple choice questions.
Ive created a statefull widget which takes the question and displays this along with 3 radio buttons as below.
Each question needs to update different property in a model defined within the parent widget.
for example:
RadioQuestionWidget("What colour is the sky?", model.ColourOfSky),
RadioQuestionWidget("What colour is the grass?", model.ColourOfGrass)
Below is my RadioQuestionWidget
import 'package:flutter/material.dart';
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question}) : super(key: key);
final String question;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
class _RadioQuestionWidgetState extends State<RadioQuestionWidget> {
String question;
var _radioValue;
#override
void initState() {
super.initState();
question = widget.question;
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
question,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Radio(
value: "Yes",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'Yes',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "No",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'No',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "Three",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
});
},
activeColor: Colors.red,
focusColor: Colors.black,
),
new Text(
'Not applicable',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
],
),
),
],
),
);
}
}
First of all, define one function in your parent widget with required arguments i.e your question number and answer.
void _updateProperty(int que_num, String ans) {
//update property according to your question number and ans
}
Now pass your function to child widget as the Constructor argument.
RadioQuestionWidget(question : "What colour is the sky?", updatePropertyHandler : _updateProperty)
Receive your function in child widget like below.
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question, this.updatePropertyHandler}) : super(key: key);
final String question;
final Function updatePropertyHandler;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
Now in your child widget while you answering the question, call _updateUi function as per your need.
Radio(
value: "Yes",
groupValue: _radioValue,
onChanged: (val) {
setState(() {
_radioValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(questionNum, _radioValue);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
)
Firstly please mark the above answer as the correct one as i couldn't have got it working without the help of #Alpesh.
I had to slightly amend the answer in order to update the correct property of the model.
This in my parent widget:
RadioQuestionWidget(
question: 'Question 1',
updatePropertyHandler: (String ans) => {
setState(() {
_qc.speedForSpeedChaeckCompleted = ans;
})
},
),
and this is my RadioQuestionWidget:
import 'package:flutter/material.dart';
class RadioQuestionWidget extends StatefulWidget {
RadioQuestionWidget({Key key, this.question, this.updatePropertyHandler})
: super(key: key);
final String question;
final Function updatePropertyHandler;
#override
_RadioQuestionWidgetState createState() => _RadioQuestionWidgetState();
}
class _RadioQuestionWidgetState extends State<RadioQuestionWidget> {
String question;
var _groupValue;
Function(String) onCountChange;
#override
void initState() {
super.initState();
question = widget.question;
_groupValue = 'Not Applicable';
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
question,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.bold),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Radio(
value: "Yes",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'Yes',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "No",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.green,
focusColor: Colors.black,
),
new Text(
'No',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
Radio(
value: "Not Applicable",
groupValue: _groupValue,
onChanged: (val) {
setState(() {
_groupValue = val;
//here questionNum is int value you need to handle question no
widget.updatePropertyHandler(val);
});
},
activeColor: Colors.red,
focusColor: Colors.black,
),
new Text(
'Not applicable',
style: new TextStyle(fontSize: 16.0, color: Colors.black),
),
],
),
),
],
),
);
}
}
Related
I'm using getx for state management,here's the video of the problem
https://drive.google.com/file/d/1tm2M46pkXVnGuf4vyh9rNs2HY2TdtBD8/view?usp=sharing
here is my code
class ActivitiesController extends GetxController {
late List<String> statusList = ["All", "Approved", "Unapproved"];
var selectedStatus = "Approved".obs;
}
#override
ActivitiesController get controller => Get.put(ActivitiesController());
in view:
const RequiredText(text: "Status"),
const SizedBox(height: Constants.defaultPadding / 2),
Obx(
() => GlobalDropDownContainer(
hintText: "All",
items: controller.statusList.toList(),
onChange: (value) {
controller.selectedStatus(value);
},
selectedValue: controller.selectedStatus.value,
)),
Here is the "GlobalDropDownContainer" code
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class GlobalDropDownContainer extends StatelessWidget {
final String hintText;
final List<String> items;
final double? width;
final Color? isNotValid;
final Function(String?) onChange;
final String? selectedValue;
const GlobalDropDownContainer({
Key? key,
required this.hintText,
required this.items,
this.width,
this.isNotValid,
required this.onChange,
this.selectedValue,
}) : super(key: key);
#override
Widget build(BuildContext context) {
Size size = Get.size;
return Container(
width: width != null ? (size.width * width!) : Get.width,
padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
border: Border.all(
width: 1,
color: isNotValid ??
Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
),
color:Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(5)),
child: DropdownButton<String>(
dropdownColor: Theme.of(context).colorScheme.background,
value: selectedValue != null && selectedValue!.isNotEmpty
? selectedValue
: null,
isExpanded: true,
underline: const SizedBox(),
hint: Text(
hintText,
style: const TextStyle(
color: Color(0xFF666666),
),
),
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground,
),
items: items.map((String value) {
return DropdownMenuItem<String>(
value: value != null && value.isNotEmpty ? value : null,
child: Text(
value,
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground),
),
);
}).toList(),
onChanged: onChange,
));
}
}
I searched for a day and i didn't find anything, i tried debug the code but it gives no warning or error. Can Anyone help me?
Try this one
Make an instance of a controller, which i presumed u have done already.
final controller = Get.put(yourgetxcontrollername());
The Widget code
Obx(
() => DropdownButton<String>(
isExpanded: true,
value: controller.selectedStatus.value,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: const TextStyle(
color: Colors.blue,
fontSize: 14,
),
onChanged: (value) {
controller.selectedStatus(
value,
);
},
items: controller.statusList.map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: const TextStyle(
color: Colors.black,
),
),
);
},
).toList(),
),
)
So im making my first Dropdown but when i have a lot of Strings it expands upwards, is there a way to compact the list and make it scrollable or am i using the wrong Widget?
class _DropdownBehaivorButton extends StatefulWidget {
const _DropdownBehaivorButton({super.key});
#override
State<_DropdownBehaivorButton> createState() => _DropdownBehaivorButtonState();
}
class _DropdownBehaivorButtonState extends State<_DropdownBehaivorButton> {
String dropdownvalue = 'Agresivo';
var tipos = [
'Agresivo',
'Tranquilo',
'Travieso',
'Docil',
'Travieso',
'Travieso',
'Travieso'
];
#override
Widget build(BuildContext context) {
return
DropdownButtonHideUnderline(
child: DropdownButton(
borderRadius: BorderRadius.circular(25),
isExpanded: true,
iconEnabledColor: Color(0xff525252),
dropdownColor: Colors.white,
style: _textStyle(),
value: dropdownvalue,
icon: const Icon(Icons.keyboard_arrow_down),
items: tipos.map((String items) {
return DropdownMenuItem(
value: items,
child: Center(child: Text(items)),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
dropdownvalue = newValue!;
});
},
),
);
}
TextStyle _textStyle() => TextStyle(
fontSize: 18,color: Color.fromARGB(123, 82, 82, 82),fontWeight: FontWeight.w400) ;}
I was expecting a compact dropdown list like this
DropdownButton(
menuMaxHeight: 100, // this line
hint: const Text(
"Please select Child / Patient"),
underline: const SizedBox(),
isExpanded: true,
iconEnabledColor: Colors.blue[800],
dropdownColor: Colors.grey[100],
style: TextStyle(
letterSpacing: 2,
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.grey[800]),
value: patientName,
items: patients.map((patient) {
return DropdownMenuItem(
value: patient,
child: Text(patient.childName),
);
}).toList(),
onChanged: (value) {
setState(() {
patientName = value;
debugPrint(patientName!
.toJson()
.toString());
});
}),
try changing the menu max height
Try to add dropdownMaxHeight: 200
Here you will find what you need https://pub.dev/packages/dropdown_button2
I'm making a page of terms and conditions.
I'm using checkboxListTile.
enter image description here
However, the Elevated Button shall be activated when selecting all items from the first to fifth items of the termsAndConditions.
The last sixth item may or may not be selected.
Otherwise, Elevated Button is disabled and the color should appear gray.
enter image description here
and Elevated Button must be activated when alltermsAndConditions are selected.
enter image description here
It’s too difficult.
Is there a solution?
I'd like to thank the people who answer.
class TermsAgreementPage extends StatelessWidget {
TermsAgreementPage({
Key? key,
}) : super(key: key);
CheckBoxState checkBoxState = Get.put(CheckBoxState(title: '', subTitle: ''));
final alltermsAndConditions = CheckBoxState(title: '전체동의', subTitle: '');
final termsAndConditions = [
CheckBoxState(
title: '이용 약관 동의(필수)',
subTitle: '니어엑스 서비스 이용 통합 약관입니다.'),
CheckBoxState(
title: '개인정보 처리방침 동의(필수)',
subTitle: '개인정보보호 포털 법률에 의거한 제공동의로 필수 사항입니다.'),
CheckBoxState(
title: '개인정보 제3자 제공동의(필수)',
subTitle: '개인정보보호 포털 법률에 의거한 제공 동의로 필수 사항입니다.'),
CheckBoxState(
title: '위치기반 서비스 이용약관(필수)',
subTitle: '주변 가게들 검색에 사용됩니다.'),
CheckBoxState(
title: '전자금융거래 이용약관(필수)',
subTitle: '구매 또는 결제 사항이 있을 경우 제공 동의로 필수 사항입니다.'),
CheckBoxState(
title: '니어엑스 혜택 알림 동의(선택)',
subTitle: '미선택 시 주변가게 할인 및 만기 다가오는 쿠폰 알림 사용 불가.'),
];
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(top: 80.0, bottom: 40),
child: Column(
children: [
Expanded(
flex: 1,
child: Container(
width: size.width,
child: Column(
children: const [
Text(
'이용 약관 동의',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'아래의 약관에 동의 하신 후 서비스를 이용해 주시기 바랍니다.',
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
color: Colors.grey),
),
],
),
),
),
Expanded(
flex: 6,
child: Obx(
() => ListView(
children: [
buildGroupCheckbox(
CheckBoxState(title: '전체동의', subTitle: '')),
const Divider(color: Colors.grey, height: 2),
...termsAndConditions.map(buildCheckbox).toList()
],
),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
padding:
const EdgeInsets.symmetric(horizontal: 50, vertical: 10),
textStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.white)),
onPressed: () {
},
child: const Text('시작하기'),
),
],
),
),
);
}
Widget buildGroupCheckbox(CheckBoxState checkBoxState) {
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
secondary: TextButton(
onPressed: () {
Get.toNamed('/home');
},
child: const Text(
'전문보기',
style: TextStyle(fontSize: 10.0, color: Colors.blue),
)),
title: Text(
checkBoxState.title,
style: const TextStyle(fontSize: 12),
),
subtitle: Text(
checkBoxState.subTitle,
style: const TextStyle(fontSize: 9, color: Colors.grey),
),
onChanged: toggleCheckBox,
value: alltermsAndConditions.isChecked.value,
);
}
void toggleCheckBox(bool? value) {
if (value == null) return;
alltermsAndConditions.isChecked.value = value;
for (var termsAndConditions in termsAndConditions) {
termsAndConditions.isChecked.value = value;
}
}
Widget buildCheckbox(CheckBoxState checkBoxState) {
return CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
// 왼쪽에 네모 박스 위치
title: Text(
checkBoxState.title,
style: const TextStyle(fontSize: 12),
),
subtitle: Text(
checkBoxState.subTitle,
style: const TextStyle(fontSize: 9, color: Colors.grey),
),
onChanged: (value) {
checkBoxState.isChecked.value = value!;
alltermsAndConditions.isChecked.value = termsAndConditions.every(
(termsAndConditions) => termsAndConditions.isChecked.value);
},
value: checkBoxState
.isChecked.value
);
}
}
********** controller **********
class CheckBoxState extends GetxController {
RxBool isChecked = false.obs;
final String title; // CheckBoxListTile 의 타이틀 제목
final String subTitle; // CheckBoxListTile 의 서브타이틀 내용
CheckBoxState({
required this.title,
required this.subTitle,
});
}
enter code here
First of all you should change this line :
termsAndConditions.map(buildCheckbox).toList()
to this :
termsAndConditions.asMap().forEach((key, value) {
buildCheckbox(value,key);
});
//or if this does work you add .toList()
termsAndConditions.asMap().forEach((key, value) {
buildCheckbox(value,key);
}).toList();
then you change the buildCheckbox function to include the key/index of the list you are passing
Widget buildGroupCheckbox(CheckBoxState checkBoxState,int index) {
...
}
then you need to add an array of booleans to keep track of the checkboxes
final checkBoxState= [false,false,false,false,false,false];
now you are implementing something like this :
onChanged: (value) {
//new code
if (value){checkBoxState[index]=true;}
else {checkBoxState[index]=false;}
checkBoxState.isChecked.value = value!;
alltermsAndConditions.isChecked.value = termsAndConditions.every(
(termsAndConditions) => termsAndConditions.isChecked.value);
},
Finally you can each individual checkbox statue and can do anything you want :
onPressed: (!sumof5first())?null:() {
//does something
},
}
bool sumof5first(){
int sum = 0;
for (int i=0;i<5;i++){
if (checkBoxState[i]==true){sum++}
}
if (sum>4){return true}
else {return false}
}
I'm making a list of notifications using switches (there will be fifteen in total), but the way I did they turn them all on and off together, how do I turn them on and off individually? And do they accept refactoring to make the code cleaner?
I'm using SwitchListTile.
class CardButton extends StatefulWidget {
const CardButton({Key? key}) : super(key: key);
#override
State<CardButton> createState() => _CardButtonState();
}
class _CardButtonState extends State<CardButton> {
bool _toggled = false;
#override
Widget build(BuildContext context) {
return Column(
children: [
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'botton',
style: TextStyle(
color: Colors.black,
),
),
value: _toggled,
onChanged: (bool value) {
setState(() => _toggled = value);
},
),
),
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'botton',
style: TextStyle(
color: Colors.black,
),
),
value: _toggled,
onChanged: (bool value) {
setState(() => _toggled = value);
},
),
),
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'botton',
style: TextStyle(
color: Colors.black,
),
),
value: _toggled,
onChanged: (bool value) {
setState(() => _toggled = value);
},
),
),
],
);
}
}
You need to create variables to hold the switch state for each switch (toggle) - in your case 15 in total.
From your sample code with individual values for each switch:
class CardButton extends StatefulWidget {
const CardButton({Key? key}) : super(key: key);
#override
State<CardButton> createState() => _CardButtonState();
}
class _CardButtonState extends State<CardButton> {
bool _switch1Toggled = false;
bool _switch2Toggled = false;
bool _switch3Toggled = false;
#override
Widget build(BuildContext context) {
return Column(
children: [
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'switch 1',
style: TextStyle(
color: Colors.black,
),
),
value: _switch1Toggled,
onChanged: (bool value) {
setState(() => _switch1Toggled = value);
},
),
),
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'switch 2',
style: TextStyle(
color: Colors.black,
),
),
value: _switch2Toggled,
onChanged: (bool value) {
setState(() => _switch2Toggled = value);
},
),
),
Card(
child: SwitchListTile(
contentPadding: EdgeInsets.only(left: 16.0),
title: Text(
'switch 3',
style: TextStyle(
color: Colors.black,
),
),
value: _switch3Toggled,
onChanged: (bool value) {
setState(() => _switch3Toggled = value);
},
),
),
],
);
}
}
Thank you very much for your tip Ranvir Mohanlal. I created this template based on your information. I think it worked better.
class MultiSwitch extends StatefulWidget {
const MultiSwitch({Key? key}) : super(key: key);
#override
State<MultiSwitch> createState() => _MultiSwitchState();
}
class _MultiSwitchState extends State<MultiSwitch> {
bool val1 = true;
bool val2 = false;
bool val3 = false;
onChangeFunction1(bool newValue1) {
setState(() {
val1 = newValue1;
});
}
onChangeFunction2(bool newValue2) {
setState(() {
val2 = newValue2;
});
}
onChangeFunction3(bool newValue3) {
setState(() {
val3 = newValue3;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
customSwitch('button', val1, onChangeFunction1),
customSwitch('button', val2, onChangeFunction2),
customSwitch('button', val3, onChangeFunction3),
],
),
);
}
}
Widget customSwitch(String text, bool val, Function onChangeMethod) {
return Card(
child: SwitchListTile(
title: Text(
text,
style: const TextStyle(
color: Colors.black,
fontSize: 18,
),
),
value: val,
onChanged: (newValue) {
onChangeMethod(newValue);
}
),
);
}
I have a dropdown button which works fine, but when I try to set a default value it will fail with the following error:
'package:flutter/src/material/dropdown.dart': Failed assertion: line 620 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == value).length == 1': is not true.
This is my dropdown button:
Widget changeWorkspace() {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: DropdownButton<AssignedWorkspace>(
isExpanded: true,
hint: Text("SELECT WORKSPACE"),
value: selectedWorkspace,
onChanged: (dropdownValueSelected) {
setState(() {
selectedWorkspace = dropdownValueSelected;
});
},
items: workspaces != null && workspaces.length > 0
? workspaces.map((AssignedWorkspace workspace) {
return new DropdownMenuItem<AssignedWorkspace>(
value: workspace,
child: new Text(workspace.name,
style: new TextStyle(color: Colors.black)),
);
}).toList()
: null),
),
]);
});
}
I've tried to set the value of selectedWorkspace onInit as follows but it fails.
selectedWorkspace = new AssignedWorkspace(
id: userSettings.currentWorkspaceId,
name: userSettings.currentWorkspaceName);
Is there a way of setting a default value in a dropdown button?
import 'package:flutter/material.dart';
import '../config/app_theme.dart';
class DropdownWidget extends StatefulWidget {
final String title;
final List<String> items;
final ValueChanged<String> itemCallBack;
final String currentItem;
final String hintText;
DropdownWidget({
this.title,
this.items,
this.itemCallBack,
this.currentItem,
this.hintText,
});
#override
State<StatefulWidget> createState() => _DropdownState(currentItem);
}
class _DropdownState extends State<DropdownWidget> {
List<DropdownMenuItem<String>> dropDownItems = [];
String currentItem;
AppTheme appTheme;
_DropdownState(this.currentItem);
#override
void initState() {
super.initState();
for (String item in widget.items) {
dropDownItems.add(DropdownMenuItem(
value: item,
child: Text(
item,
style: TextStyle(
fontSize: 16,
),
),
));
}
}
#override
void didUpdateWidget(DropdownWidget oldWidget) {
if (this.currentItem != widget.currentItem) {
setState(() {
this.currentItem = widget.currentItem;
});
}
super.didUpdateWidget(oldWidget);
}
#override
Widget build(BuildContext context) {
appTheme = AppTheme(Theme.of(context).brightness);
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 6),
child: Text(
widget.title,
style: appTheme.activityAddPageTextStyle,
),
),
Container(
padding: EdgeInsets.symmetric(vertical: 3, horizontal: 15),
margin: EdgeInsets.only(top: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 2),
blurRadius: 10,
color: Color(0x19000000),
),
],
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
icon: appTheme.activityAddPageDownArrowSVG,
value: currentItem,
isExpanded: true,
items: dropDownItems,
onChanged: (selectedItem) => setState(() {
currentItem = selectedItem;
widget.itemCallBack(currentItem);
}),
hint: Container(
child: Text(widget.hintText, style: appTheme.hintStyle),
),
),
),
),
],
),
);
}
}
This is my dropDownWidget without optimization. It has currentItem. You could use it like:
DropdownWidget(
title: kStatus,
items: state.customerStepInfo.statusList,
currentItem: status,
hintText: kCommonPick,
itemCallBack: (String status) {
this.status = status;
},
)
You need implement "equals" in class AssignedWorkspace. I used equatable package.
Example class AssignedWorkspace
class AssignedWorkspace extends Equatable {
final String id;
final String name;
AssignedWorkspace(this.id, this.name);
#override
List<Object> get props => [id];
}
For me id of one of the element is null, once added id is made non-null issue got fixed.
I changed the value of the dropdown var to 1 initially
var _value = '1';
So when the dropdown button has to display its value it displays the one whose value I have set 1 as in the items list in DropDownButton
DropdownButton(
underline: Container(),
onChanged: (value) {
setState(() {
_value = value;
});
},
value: _value,
items: [
DropdownMenuItem(
value: "1",
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(MaterialCommunityIcons.devices),
SizedBox(width: 10),
Text(
"Consumption",
style: TextStyle(
fontSize: 18.0, fontWeight: FontWeight.w600),
),
],
),
),
DropdownMenuItem(
value: "2",
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(MaterialCommunityIcons.solar_panel),
SizedBox(width: 10),
Text(
"Generation",
style: TextStyle(
fontSize: 18.0, fontWeight: FontWeight.w600),
),
],
),
),
],
),
if you want to see only an initial value you can use hint text named parameter of drop down button and set a text widget. i dont know whether it is a good practice or not.