Flutter how change dropdownlist item color - flutter

I want to make the color of the values ​​in the hour list yellow with the data in the selected list. Here is the code for the dropdown list and screenshot. how can I do that.
enter image description here
import 'package:flutter/material.dart';
class deneme extends StatefulWidget {
#override
_denemeState createState() => _denemeState();
}
class _denemeState extends State<deneme> {
List<String> hour = ["09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00"];
List<String> selected = ["09:00", "12:00", "16:00"];
int hourId;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Deneme"),
),
body: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent, width: 2),
borderRadius: BorderRadius.all((Radius.circular(10)))),
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 24),
margin: EdgeInsets.all(12),
child: DropdownButtonHideUnderline(
child: DropdownButton<int>(
items: hour.map((h) {
return DropdownMenuItem<int>(
child: Text(
h,
style: TextStyle(fontSize: 24),
),
value: hour.indexOf(h),
);
}).toList(),
value: hourId,
onChanged: (secilenOncelikId) {
setState(() {
hourId = secilenOncelikId;
});
},
hint: Text("Select Hour"),
),
),
),
);
}
}

Just compute the background color for each item: var backgroundColor = (selected.contains(h)) ? Colors.yellow : Colors.white; and assign it in your existing TextStyle:
child: DropdownButton<int>(
items: hour.map((h) {
var backgroundColor = (selected.contains(h)) ? Colors.yellow : Colors.white;
return DropdownMenuItem<int>(
child: Text(
h,
style: TextStyle(
fontSize: 24,
backgroundColor: backgroundColor,
),
),
value: hour.indexOf(h),
);
}).toList(),
value: hourId,
onChanged: (secilenOncelikId) {
setState(() {
hourId = secilenOncelikId;
});
},
hint: Text("Select Hour"),
),
Results:

you can wrap your child of Drop down Menu Item child (text) by colored container

Related

How to change button color and move to home when selecting 5 checklists or selecting all in flutter

I'm making a contract terms page. Checkbox ListTile is being used.
There is a total agreement and six items.
If the first to fifth items of the Terms and Conditions are selected, the Elevated Button color should be changed to blue and made available to move home (screenshot).
If all items are selected, the Elevated Button color should be changed to blue and made to be able to move home (screenshot).
Other than that, Elevated Button is grey and cannot be moved home (screenshot).
I tried it, but it's so hard to set the index for each item
Is there a solution?
Thank you to those who answered.
class TermsAgreementPage extends StatelessWidget {
TermsAgreementPage({
Key? key,
}) : super(key: key);
CheckBoxState checkBoxState = Get.put(CheckBoxState(''));
final alltermsAndConditions = CheckBoxState('');
final termsAndConditions = [
CheckBoxState('이용 약관 동의(필수)', '니어엑스 서비스 이용 통합 약관입니다.'),
CheckBoxState('개인정보 처리방침 동의(필수)', '개인정보보호 포털 법률에 의거한 제공동의로 필수 사항입니다.'),
CheckBoxState('개인정보 제3자 제공동의(필수)', '개인정보보호 포털 법률에 의거한 제공 동의로 필수 사항입니다.'),
CheckBoxState('위치기반 서비스 이용약관(필수)', '주변 가게들 검색에 사용됩니다.'),
CheckBoxState('전자금융거래 이용약관(필수)', '구매 또는 결제 사항이 있을 경우 제공 동의로 필수 사항입니다.'),
CheckBoxState('니어엑스 혜택 알림 동의(선택)','미선택 시 주변가게 할인 및 만기 다가오는 쿠폰 알림 사용 불가.')
];
#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: SizedBox(
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('전체동의')),
Divider(color: Colors.grey[300], height: 5, thickness: 3),
...termsAndConditions.map(buildCheckbox).toList(),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: termsAndConditions.every((termsAndConditions) => termsAndConditions.isChecked.value)
? Colors.blue
: Colors.grey[400],
padding: const EdgeInsets.symmetric(
horizontal: 150, vertical: 10),
textStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.white)),
onPressed: () {
if(alltermsAndConditions.isChecked.value) {
Get.toNamed('/home');
}
},
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: 15, fontWeight: FontWeight.w500),
),
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 // checkBoxState 의 isChecked 값임 (false 상태)
);
}
}
class CheckBoxState extends GetxController {
RxBool isChecked = false.obs;
String title;
String subTitle;
CheckBoxState(this.title,[this.subTitle = '']);
}
It's possible to use getRange to get the items from 0 to 4 (The first 5 items). And then, just iterate over every one of them to check if all of them are checked.
Just change the line:
primary: termsAndConditions.every((termsAndConditions) => termsAndConditions.isChecked.value)
? Colors.blue
: Colors.grey[400],
To the following:
primary: termsAndConditions.getRange(0, 4).every(
(termsAndConditions) => termsAndConditions.isChecked.value)
? Colors.blue
: Colors.grey[400],
And also the onPressed property from:
onPressed: () {
if (allTermsAndConditions.isChecked.value) {
Get.toNamed('/home');
}
},
To the following:
onPressed: () {
if (termsAndConditions.getRange(0, 4).every(
(termsAndConditions) =>
termsAndConditions.isChecked.value)) {
Get.toNamed('/home');
}
},

how to Activate Elevatedbutton when checkboxListTile is selected

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}
}

Flutter: Update children state from change in parent

NOTE: The code may seem very long, but for this question you don't need to understand every part of it.
I have an app, which gets data from an API to build a chart with it. I use the Syncfusion cartesian chart package. This is an economic indicator, so it brings a date and a value, for example:
[[2015 Oct, 0.24],[2015 Nov, 0.26],[2015 Dec, 0.32],[2016 Jan, 0.35],[2016 Feb, 0.40],[2016 Mar, 0.48]]
So, once the data arrives (It has a loading screen for waiting the data form the HTTP request), I build the chart with it.
So in this case, my Parent widget is named ChartScreen. Here's the code:
class ChartScreen extends StatefulWidget {
#override
State<ChartScreen> createState() => _ChartScreenState();
}
class _ChartScreenState extends State<ChartScreen> {
String dropdownValue = '';
initState() {
dropdownValue = '2016';
return super.initState();
}
#override
Widget build(BuildContext context) {
final enterpriseProvider = Provider.of<EnterpriseProvider>(context);
final resp = enterpriseProvider.indicator;
List<IpcData> data = _createIpcList(resp, dropdownValue);
if( data.length == 0 ) {
return Scaffold(
appBar: AppBar(
title: Text('Obteniendo datos...'),
),
body: Container(
color: Colors.black,
width: double.infinity,
height: double.infinity,
child: Center(
child: CircularProgressIndicator(),
),
),
);
}
return
Scaffold(
appBar: AppBar(
title: Text('IPC'),
actions:[
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButton(
value: dropdownValue,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.white),
underline: Container(
height: 2,
color: Colors.white,
),
onChanged: (String? newValue) {
dropdownValue = newValue!;
data = _createIpcList(resp, dropdownValue);
setState(() {});
},
items: <String>['2016', '2017', '2018', '2019']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()
),
)
]
),
drawer: SideMenu(),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Container(
child: ResultChart( formattedData: data )###############################
),
),
],
)
);
}
_createIpcList(List<List<dynamic>> resp, [String? year]) {
print('EL AÑOO');
print(year);
List<IpcData>finalList = [];
if(resp.length != 0) {
for(int i = 0; i < resp.length; i++) {
try {
resp[i][0] = DateFormat.yMMM().format(DateTime.parse(resp[i][0]));
} catch(e) {}
}
}
List<IpcData> ipcList = resp.map((e) => IpcData(e[0], e[1])).toList();
if (year!= null) {
for(int i = 0; i < ipcList.length; i++){
if (ipcList[i].date.contains(year)){
finalList.add(ipcList[i]);
}
}
}
return finalList;
}
}
With the _createIpcList I format the JSON data, so the chart can use it. I highlighted the line in which I call the child whose state I want to update. But before that, you can se that I added a dropdown menu, to select a year from a (hardcoded) list. When the dropdown menu selected item changes (see onChanged), I call the SetState and pass the 'year parameter' to the _createIpcList, which filters the data and returns the items that belong to the selected year. Here's the child code:
class ResultChart extends StatefulWidget {
final List<IpcData> formattedData;
const ResultChart({
Key? key,
required this.formattedData
}) : super(key: key);
#override
_ResultChartState createState() => _ResultChartState();
}
class _ResultChartState extends State<ResultChart> {
late List<IpcData> _chartData;
#override
void initState() {
_chartData = widget.formattedData;
super.initState();
}
#override
Widget build(BuildContext context) {
return Container(
child: SfCartesianChart(
backgroundColor: Colors.black,
enableAxisAnimation: false,
trackballBehavior: TrackballBehavior(
enable: true,
shouldAlwaysShow: true,
tooltipSettings: InteractiveTooltip(
borderWidth: 2,
borderColor: Colors.grey,
color: Colors.grey[400],
format: 'point.x : point.y'
)
),
zoomPanBehavior: ZoomPanBehavior(
enablePanning: true,
enablePinching: true,
enableDoubleTapZooming: true,
zoomMode: ZoomMode.xy,
),
primaryXAxis: CategoryAxis(
labelRotation: 90,
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[400]
),
axisLine: AxisLine(
width: 2,
color: Colors.grey
),
majorGridLines: MajorGridLines(width: 1),
),
primaryYAxis: NumericAxis(
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.grey[400]
),
axisLine: AxisLine(
width: 2,
color: Colors.grey
),
title: AxisTitle( text: 'IPC', textStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
majorGridLines: MajorGridLines(width: 1),
),
series: <ChartSeries>[
LineSeries<IpcData, String>(
color: Colors.blue,
dataSource: _chartData,
xValueMapper: (IpcData data, _) => data.date,
yValueMapper: (IpcData data, _) => data.value
)
],)
);
}
}
class IpcData {
final String date;
final double value;
IpcData(this.date, this.value);
}
My problem is that, no matter which year I select, the chart doesn't change. I know that the 'dropdownValue' changes because I debugged with some prints() but I don´t know how to rebuild or set state of the ResultChart widget.
Well it turn out that I continued debugging, and actually the ResultChart widget was being rebuilt again and again, but I never called the setState function inside the children. Beginner error I know, but I'm new with Flutter.

How to make a button select all Flutter checkboxes?

The problem is that I cannot make the button select all checkboxes, since I am using an automatically generated list of checkboxes.
Since I created a class with a list item, WordBlock, which is a container with a Checkbox and each checkbox has its own checked value, and therefore I can not select everything in any way. And if I set the checked value through the constructor, then it selects everything, but the onChanged () method does not work and the value of one checkbox does not change. But you need to be able to select the checkboxes one at a time or all at once, select all with the button.
Here is the code for my WordBlock class that appears in the list.
class WordBlock extends StatefulWidget {
final bool checkAll;
WordBlock(this.checkAll);
#override
_WordBlockState createState() => _WordBlockState();
}
class _WordBlockState extends State<WordBlock> {
FlutterTts tts = FlutterTts();
bool checked = false;
Future _speak(String text) async {
await tts.setLanguage('en-US');
await tts.speak(text);
}
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 35.w),
child: Card(
color: checked ? MyColors().scaffoldBG : Colors.white,
elevation: 4.0,
shadowColor: MyColors().black.withOpacity(0.1),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.ssp)),
child: CheckboxListTile(
value: checked,
activeColor: MyColors().purple,
onChanged: (value) {
print('changed');
setState(() {
checked = value;
});
},
title: h2(text: 'Car'),
secondary: Padding(
padding: EdgeInsets.only(top: 10.h),
child: InkWell(
onTap: () => _speak('Car'),
child: Icon(
Icons.volume_up_rounded,
color: MyColors().purple,
size: 60.ssp,
),
),
),
subtitle: Text(
'Машина',
style: TextStyle(color: Color(0xFFB8A98BA), fontSize: 27.ssp),
),
),
),
);
}
}
Here is the code for my page that displays the WordBloc list:
class WordPage extends StatefulWidget {
#override
_WordPageState createState() => _WordPageState();
}
class _WordPageState extends State<WordPage> {
bool visible = true;
double banerHeight;
bool checked = false;
#override
void initState() {
super.initState();
}
Widget _wrapWithBanner() {
if (!visible) {
setState(() {
banerHeight = 0;
});
}
return visible
? Container(
margin: EdgeInsets.only(
left: 35.w, right: 35.w, top: 30.h, bottom: 30.h),
padding: EdgeInsets.symmetric(vertical: 25.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.ssp),
color: MyColors().scaffoldBG,
boxShadow: [boxShadow4Y10Blur()]),
child: ListTile(
onTap: () {
print('close');
},
trailing: visible
? InkWell(
onTap: () {
print('tapped');
setState(() {
visible = false;
});
},
child: Icon(Icons.close))
: Container(),
leading: CircleAvatar(),
title: h3bold(text: 'Совет'),
subtitle: Text(
'Чтобы запомнить как можно больше слов, регулярно повторяйте их: каждые два-три часа :)',
style: TextStyle(color: MyColors().black, fontSize: 27.ssp),
),
))
: Container();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: MyColors().white,
appBar: AppBar(
elevation: 2.0,
title: h2(text: 'Работа'),
iconTheme: IconThemeData(size: 20.ssp, color: MyColors().purple),
backgroundColor: MyColors().white,
),
body: Column(
children: [
_wrapWithBanner(),
Row(
children: [
FlatButton( // my selectAll button
onPressed: () {},
child: Row(
children: [
Checkbox(
value: checked,
onChanged: (val) {
setState(() {
checked = val;
});
}),
Text(
'Выделить все',
style: TextStyle(
color: MyColors().purple, fontSize: 27.ssp),
)
],
))
],
),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (context, index) {
return WordBlock(checked);
},
))
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Container(
width: 667.w,
height: 91.h,
child: FloatingActionButton(
backgroundColor: MyColors().purple,
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24.ssp)),
child: h2reg(
text: "Добавить в мой словарь", textColor: MyColors().white),
),
),
));
}
}
How can this function be implemented?
If you put bool checked = false; in as
class WordBlock extends StatefulWidget {
bool checked = false;
WordBlock();
#override
_WordBlockState createState() => _WordBlockState();
}
You can change it and reach it from _WordBlockState as widget.checked
Checkbox(
value: widget.checked,
onChanged: (val) {
setState(() {
widget.checked = val;
});
}),
it can be modified by both class and not constant.
try below code for with button all checkbox check and uncheck
Output :-
Code :-
import 'package:flutter/material.dart';
class CheckBoxExample extends StatefulWidget {
const CheckBoxExample({Key? key}) : super(key: key);
#override
State<CheckBoxExample> createState() => _CheckBoxExampleState();
}
class _CheckBoxExampleState extends State<CheckBoxExample> {
List multipleSelected = [];
List checkListItems = [
{
"id": 0,
"value": false,
"title": "Sunday",
},
{
"id": 1,
"value": false,
"title": "Monday",
},
{
"id": 2,
"value": false,
"title": "Tuesday",
},
{
"id": 3,
"value": false,
"title": "Wednesday",
},
{
"id": 4,
"value": false,
"title": "Thursday",
},
{
"id": 5,
"value": false,
"title": "Friday",
},
{
"id": 6,
"value": false,
"title": "Saturday",
},
];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
child: Column(
children: [
InkWell(
onTap: () => setState(() {
multipleSelected.clear();
for (var element in checkListItems) {
if (element["value"] == false) {
element["value"] = true;
multipleSelected.add(element);
} else {
element["value"] = false;
multipleSelected.remove(element);
}
}
}),
child: const Text(
"Select All",
style: TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
Column(
children: List.generate(
checkListItems.length,
(index) => CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(
checkListItems[index]["title"],
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
),
),
value: checkListItems[index]["value"],
onChanged: (value) {
setState(() {
checkListItems[index]["value"] = value;
});
},
),
),
),
Text(
multipleSelected.isEmpty ? "" : multipleSelected.toString(),
style: const TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}

How to add another List of item for DropDownMenu, and then use the items in widget

So I'm trying to make a drop down menu for each options and insert a different List of items each. First of all, because my Dropdownmenu widget shares the same properties for one and another, I extracted the widget to another class name "MenuDropDown". Here is the code for the widget.
import 'package:flutter/material.dart';
import 'List.dart';
class MenuDropDown extends StatefulWidget {
final String dropdownText;
final List<DropdownMenuItem<String>> itemList;
MenuDropDown({this.dropdownText, this.itemList});
#override
_MenuDropDownState createState() => _MenuDropDownState();
}
class _MenuDropDownState extends State<MenuDropDown> {
String selectedItem;
List<DropdownMenuItem> getGroomingTypeList() {
List<DropdownMenuItem<String>> dropdownItems = [];
for (String groomingType in groomingTypeList) {
var newItem = DropdownMenuItem(
child: Text(groomingType),
value: groomingType,
);
dropdownItems.add(newItem);
}
return dropdownItems;
}
List<DropdownMenuItem> getCatBreedsList() {
List<DropdownMenuItem<String>> dropdownItems = [];
for (String catBreed in catBreedsList) {
var newItem = DropdownMenuItem(
child: Text(catBreed),
value: catBreed,
);
dropdownItems.add(newItem);
}
return dropdownItems;
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 8.0, 0, 10.0),
child: Container(
width: 325.0,
height: 50.0,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(2.5, 5.5),
blurRadius: 5.0,
)
],
borderRadius: BorderRadius.circular(8),
color: Colors.white,
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: selectedItem,
hint: Padding(
padding: const EdgeInsets.fromLTRB(22.0, 0, 0, 0),
child: Text(
widget.dropdownText,
style: TextStyle(),
),
),
items: widget.itemList,
onChanged: (value) {
setState(() {
selectedItem = value;
});
}),
),
),
);
}
}
above here I created a method to get the list item from the list class that I already created, First it works if I hardcoded the method into the Dropdownmenu's items properties to show the item list, but because I need to use the different list for the different widget, so I think if I try to create a variable of List named itemList, so I can access it from the other class where I can call just the customized variable.
And this is the Stateful widget where i use my Extracted Dropdownmenu widget :
import 'package:flutter/material.dart';
import 'TitleName.dart';
import 'dropdownmenu.dart';
class InformationDetail extends StatefulWidget {
#override
_InformationDetailState createState() => _InformationDetailState();
}
class _InformationDetailState extends State<InformationDetail> {
MenuDropDown _menuDropDown = MenuDropDown();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 70.0, 26.0),
child: Text(
'Information Detail',
style: TextStyle(fontSize: 35.0),
),
),
Column(
// Wrap Column
children: <Widget>[
Column(
children: <Widget>[
TitleName(
titleText: 'Grooming Type',
infoIcon: Icons.info,
),
MenuDropDown(
dropdownText: 'Grooming Type...',
//I'm trying to implement the list here with a custom variable that contain
a method with different list in dropdownmenu class
itemlist: getGroomingTypeList(),
),
TitleName(
titleText: 'Cat Breeds',
),
MenuDropDown(
dropdownText: 'Cat Breeds...',
),
TitleName(
titleText: 'Cat Size',
infoIcon: Icons.info,
),
MenuDropDown(
dropdownText: 'Cat Size...',
),
TitleName(
titleText: 'Add-On Services',
),
MenuDropDown(
dropdownText: 'Add - On Services...',
),
Container(
margin: EdgeInsets.fromLTRB(0, 15.0, 0, 0),
width: 75.0,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
border: Border.all(
color: Colors.black,
),
borderRadius: BorderRadius.circular(12.0),
),
child: IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () {
Navigator.of(context)
.pushNamed('/ReservationDetail');
},
),
),
],
),
],
),
],
),
),
),
);
}
}
And this is the list that I want to use for each of dropdown menu widget
const List groomingTypeList = ['Basic Grooming', 'Full Grooming'];
const List catBreedsList = [
'Persia',
'Anggora',
'Domestic',
'Maine Coon',
'Russian Blue',
'Slamese',
'Munchkin',
'Ragdoll',
'Scottish Fold',
];
const List catSizeList = [
'Small Size',
'Medium Size',
'Large Size',
'Extra Large Size',
];
const List addOnServicesList = [
'Spa & Massage',
'Shaving Hair / Styling',
'Injection Vitamis Skin & Coat',
'Cleaning Pet House and Environment',
'Fur Tangled Treatment',
];
I got stuck from there. How to use a different list for each dropdown menu widget that I made, because I already tried to make a constructor, variable, and method so I can use it separately, but instead I got an error that says,
type 'List' is not a subtype of type 'List<DropdownMenuItem>'
I think I implemented it in the wrong way in the first place. I really need help with another solution to these problems. thank you, everyone!
Just check out the code that I have made some changes :
import 'package:flutter/material.dart';
void main() => runApp(InformationDetail());
class InformationDetail extends StatefulWidget {
#override
_InformationDetailState createState() => _InformationDetailState();
}
class _InformationDetailState extends State<InformationDetail> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 70.0, 26.0),
child: Text(
'Information Detail',
style: TextStyle(fontSize: 35.0),
),
),
Column(
// Wrap Column
children: <Widget>[
Column(
children: <Widget>[
Text(
'Grooming Type',
),
MenuDropDown(
dropdownText: 'Grooming Type...',
//I'm trying to implement the list here with a custom variable that contain
// a method with different list in dropdownmenu class
type: "groomingType",
),
Text(
'Cat Breeds',
),
MenuDropDown(
dropdownText: 'Cat Breeds...',
type: "catBreeds",
),
Text(
'Cat Size',
),
MenuDropDown(
dropdownText: 'Cat Size...',
type: "catSize",
),
Text(
'Add-On Services',
),
MenuDropDown(
dropdownText: 'Add - On Services...',
type: "addOnServices",
),
Container(
margin: EdgeInsets.fromLTRB(0, 15.0, 0, 0),
width: 75.0,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
border: Border.all(
color: Colors.black,
),
borderRadius: BorderRadius.circular(12.0),
),
child: IconButton(
icon: Icon(Icons.arrow_forward),
onPressed: () {
Navigator.of(context)
.pushNamed('/ReservationDetail');
},
),
),
],
),
],
),
],
),
),
),
),
);
}
}
class MenuDropDown extends StatefulWidget {
final String dropdownText;
final String type;
MenuDropDown({this.dropdownText, this.type});
#override
_MenuDropDownState createState() => _MenuDropDownState();
}
class _MenuDropDownState extends State<MenuDropDown> {
String selectedItem;
List<String> dropdownItems = [];
List<String> groomingTypeList = ['Basic Grooming', 'Full Grooming'];
List<String> catBreedsList = [
'Persia',
'Anggora',
'Domestic',
'Maine Coon',
'Russian Blue',
'Slamese',
'Munchkin',
'Ragdoll',
'Scottish Fold',
];
List<String> catSizeList = [
'Small Size',
'Medium Size',
'Large Size',
'Extra Large Size',
];
List<String> addOnServicesList = [
'Spa & Massage',
'Shaving Hair / Styling',
'Injection Vitamis Skin & Coat',
'Cleaning Pet House and Environment',
'Fur Tangled Treatment',
];
List<String> getListBasedOnName(String value) {
print(value);
switch (value) {
case "groomingType":
return groomingTypeList;
break;
case "catBreeds":
return catBreedsList;
break;
case "catSize":
return catSizeList;
break;
case "addOnServices":
return addOnServicesList;
break;
}
return null;
}
#override
void initState() {
super.initState();
print(widget.type);
dropdownItems = getListBasedOnName(widget.type);
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 8.0, 0, 10.0),
child: Container(
width: 325.0,
height: 50.0,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(2.5, 5.5),
blurRadius: 5.0,
)
],
borderRadius: BorderRadius.circular(8),
color: Colors.white,
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: selectedItem,
hint: Padding(
padding: const EdgeInsets.fromLTRB(22.0, 0, 0, 0),
child: Text(
widget.dropdownText,
style: TextStyle(),
),
),
items: dropdownItems.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedItem = value;
});
}),
),
),
);
}
}
As some of the widgets were missing, I have added mine you can change as per your needs. Let me know if it works.