This is the interface that I made What I need to do is to disable the "Select" button when there is no chip selected but I'm new to flutter and I'm still confused how to work on this logic. Is there any way to do it?
This is the codes that I used:
import 'package:flutter/material.dart';
class ChipDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ChipDemoState();
}
class _ChipDemoState extends State<ChipDemo> {
late GlobalKey<ScaffoldState> _key;
late bool _isSelected;
late List<FilterWidget> _status;
late List<FilterWidget> _projectCode;
late List<FilterWidget> _labor;
late List<String> _statusFilters;
late List<String> _projectCodeFilters;
late List<String> _laborFilters;
String pickedStartDate = 'Pick the start date';
String pickedEndDate = 'Pick the end date';
DateTime selectedStartDate = DateTime.now();
DateTime selectedEndDate = DateTime.now();
DateTime ? startDate;
DateTime ? endDate;
@override
void initState() {
super.initState();
_key = GlobalKey<ScaffoldState>();
_isSelected = false;
_statusFilters = <String>[];
_projectCodeFilters = <String>[];
_laborFilters = <String>[];
_status = <FilterWidget>[
FilterWidget('WAPPR'),
FilterWidget('APPR'),
];
_projectCode = <FilterWidget>[
FilterWidget('PRO-101'),
FilterWidget('PRO-102'),
FilterWidget('PRO-103'),
FilterWidget('PRO-104'),
FilterWidget('PRO-105'),
FilterWidget('PRO-106'),
FilterWidget('PRO-107'),
FilterWidget('PRO-108'),
];
_labor = <FilterWidget>[
FilterWidget('Bimo'),
FilterWidget('Raka'),
FilterWidget('Juan'),
FilterWidget('Panji'),
FilterWidget('Septa'),
FilterWidget('Rifaldi'),
FilterWidget('Hansen'),
FilterWidget('Satrio'),
];
}
String getStartDateText(){
if (startDate == null){
return 'Select Date';
}else {
return '${startDate!.month}/${startDate!.day}/${startDate!.year}';
}
}
String getEndDateText(){
if (endDate == null){
return 'Select Date';
}else {
return '${endDate!.month}/${endDate!.day}/${endDate!.year}';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _key,
appBar: AppBar(
title: const Text("My Team",
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
backgroundColor: Colors.white,
centerTitle: true,
automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const Text('Status',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: statusPosition.toList(),
),
const SizedBox(
height: 10,
),
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children:[
const Text('Start Date',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
OutlinedButton(
onPressed: () {
_selectStartDate(context);
},
style: OutlinedButton.styleFrom(
side: BorderSide(width: 1.0, color: Colors.grey),
),
child: Text(getStartDateText(),
style: TextStyle(color: Colors.grey),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children:[
const Text('End Date',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
OutlinedButton(
onPressed: () {
_selectEndDate(context);
},
style: OutlinedButton.styleFrom(
side: BorderSide(width: 1.0, color: Colors.grey),
),
child: Text(getEndDateText(),
style: TextStyle(color: Colors.grey),
),
),
],
),
],
),
const SizedBox(
height: 10,
),
const Text('Project Code',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: projectCodePosition.toList(),
),
Row(
children: [
SizedBox.fromSize(),
Spacer(),
Container(
height: 50 ,
width: 150 ,
padding: EdgeInsets.only(right:15),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),
)
)
),
onPressed: () async {
},
child: Text('Select', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontFamily: "Roboto", fontSize: 16.0,)),
),
),
],
),
const Text('Labor',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: laborPosition.toList(),
),
],
)
),
),
bottomNavigationBar: Card(
child : Container(
padding: EdgeInsets.all(12.0),
height: 86,
decoration: const BoxDecoration(
color: Colors.white,
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black54,
blurRadius: 20.0,
spreadRadius: -20.0,
offset: Offset(0.0, -15.0),
)
],
),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),
)
)
),
onPressed: () async {
},
child: Text('Search', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontFamily: "Roboto", fontSize: 16.0,)),
),
),
),
);
}
Future _selectStartDate(BuildContext context) async {
final newDate = await showDatePicker(
context: context,
initialDate: selectedStartDate,
firstDate: DateTime(2010),
lastDate: DateTime(2025),
);
if (newDate == null) return;
setState(() => startDate = newDate);
}
_selectEndDate(BuildContext context) async {
final newDate = await showDatePicker(
context: context,
initialDate: selectedEndDate,
firstDate: DateTime(2010),
lastDate: DateTime(2025),
);
if (newDate == null) return;
setState(() => endDate = newDate);
}
Iterable<Widget> get statusPosition sync* {
for (FilterWidget company in _status) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
avatar: CircleAvatar(
backgroundColor: Colors.cyan,
child: Text(
company.name[0].toUpperCase(),
style: TextStyle(color: Colors.white),
),
),
label: Text(
company.name,
style: TextStyle(color: _isSelected == false ? Colors.grey : Colors.white,
fontFamily: "Roboto",
),
),
selected: _statusFilters.contains(company.name),
checkmarkColor: Colors.white,
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_statusFilters.add(company.name);
} else {
_statusFilters.removeWhere((String name) {
return name == company.name;
});
}
print(_statusFilters.toString());
});
},
),
);
}
}
Iterable<Widget> get projectCodePosition sync* {
for (FilterWidget company in _projectCode) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
label: Text(
company.name,
style: TextStyle(color: _isSelected == false ? Colors.grey : Colors.white,
fontFamily: "Roboto",
),
),
selected: _projectCodeFilters.contains(company.name),
checkmarkColor: Colors.white,
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_projectCodeFilters.add(company.name);
} else {
_projectCodeFilters.removeWhere((String name) {
return name == company.name;
});
}
print(_projectCodeFilters.toString());
});
},
),
);
}
}
Iterable<Widget> get laborPosition sync* {
for (FilterWidget company in _labor) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white60,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
avatar: CircleAvatar(
backgroundColor: Colors.cyan,
child: Text(
company.name[0].toUpperCase(),
style: TextStyle(color: Colors.white),
),
),
label: Text(
company.name,
style: TextStyle(color: Colors.grey,
fontFamily: "Roboto", ),
),
selected: _laborFilters.contains(company.name),
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_laborFilters.add(company.name);
} else {
_laborFilters.removeWhere((String name) {
return name == company.name;
});
}
print(_laborFilters.toString());
});
},
),
);
}
}
}
class FilterWidget {
const FilterWidget(this.name);
final String name;
}
.....................................................................................................
CodePudding user response:
add the chip click to a empty list then check if list is empty...
CodePudding user response:
Declare a bool called activateButton, set it to true whenever a chip is selected and whenever any of the chips is unselected check the length of the _projectCodeFilters array if it returns to the original length then nothing selected. Also, I manipulated the onPress function, you have to do nothing whenever your flag is FALSE, moreover the button color is grey when the flag is FALSE.
P.S I manipulated the code on dartpad so, I removed the null saftey, just re-check for null.
import 'package:flutter/material.dart';
void main() {
// any preprocessing can be done here, such as determining a device location
//
// runApp is a Flutter function that runs your Flutter app
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: ChipDemo(),
),
);
}
}
class ChipDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ChipDemoState();
}
class _ChipDemoState extends State<ChipDemo> {
GlobalKey<ScaffoldState> _key;
bool _isSelected;
List<FilterWidget> _status;
List<FilterWidget> _projectCode;
List<FilterWidget> _labor;
List<String> _statusFilters;
List<String> _projectCodeFilters;
List<String> _laborFilters;
String pickedStartDate = 'Pick the start date';
String pickedEndDate = 'Pick the end date';
DateTime selectedStartDate = DateTime.now();
DateTime selectedEndDate = DateTime.now();
DateTime startDate;
DateTime endDate;
bool activateButton = false;
@override
void initState() {
super.initState();
_key = GlobalKey<ScaffoldState>();
_isSelected = false;
_statusFilters = <String>[];
_projectCodeFilters = <String>[];
_laborFilters = <String>[];
_status = <FilterWidget>[
FilterWidget('WAPPR'),
FilterWidget('APPR'),
];
_projectCode = <FilterWidget>[
FilterWidget('PRO-101'),
FilterWidget('PRO-102'),
FilterWidget('PRO-103'),
FilterWidget('PRO-104'),
FilterWidget('PRO-105'),
FilterWidget('PRO-106'),
FilterWidget('PRO-107'),
FilterWidget('PRO-108'),
];
_labor = <FilterWidget>[
FilterWidget('Bimo'),
FilterWidget('Raka'),
FilterWidget('Juan'),
FilterWidget('Panji'),
FilterWidget('Septa'),
FilterWidget('Rifaldi'),
FilterWidget('Hansen'),
FilterWidget('Satrio'),
];
}
String getStartDateText() {
if (startDate == null) {
return 'Select Date';
} else {
return '${startDate.month}/${startDate.day}/${startDate.year}';
}
}
String getEndDateText() {
if (endDate == null) {
return 'Select Date';
} else {
return '${endDate.month}/${endDate.day}/${endDate.year}';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _key,
appBar: AppBar(
title: const Text(
"My Team",
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
backgroundColor: Colors.white,
centerTitle: true,
automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const Text(
'Status',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: statusPosition.toList(),
),
const SizedBox(
height: 10,
),
Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
'Start Date',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
OutlinedButton(
onPressed: () {
_selectStartDate(context);
},
style: OutlinedButton.styleFrom(
side: BorderSide(width: 1.0, color: Colors.grey),
),
child: Text(
getStartDateText(),
style: TextStyle(color: Colors.grey),
),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text(
'End Date',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
OutlinedButton(
onPressed: () {
_selectEndDate(context);
},
style: OutlinedButton.styleFrom(
side: BorderSide(width: 1.0, color: Colors.grey),
),
child: Text(
getEndDateText(),
style: TextStyle(color: Colors.grey),
),
),
],
),
],
),
const SizedBox(
height: 10,
),
const Text(
'Project Code',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: projectCodePosition.toList(),
),
Row(
children: [
SizedBox.fromSize(),
Spacer(),
Container(
height: 50,
width: 150,
padding: EdgeInsets.only(right: 15),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
activateButton == true
? Color(0xFF023E8A)
: Colors.grey),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
))),
onPressed: () async {
if (activateButton == true) {
//do whatever you want
} else {
//don't do anything
}
},
child: Text('Select',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontFamily: "Roboto",
fontSize: 16.0,
)),
),
),
],
),
const Text(
'Labor',
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: "Roboto",
),
),
Wrap(
children: laborPosition.toList(),
),
],
)),
),
bottomNavigationBar: Card(
child: Container(
padding: EdgeInsets.all(12.0),
height: 86,
decoration: const BoxDecoration(
color: Colors.white,
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black54,
blurRadius: 20.0,
spreadRadius: -20.0,
offset: Offset(0.0, -15.0),
)
],
),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
))),
onPressed: () async {},
child: Text('Search',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontFamily: "Roboto",
fontSize: 16.0,
)),
),
),
),
);
}
Future _selectStartDate(BuildContext context) async {
final newDate = await showDatePicker(
context: context,
initialDate: selectedStartDate,
firstDate: DateTime(2010),
lastDate: DateTime(2025),
);
if (newDate == null) return;
setState(() => startDate = newDate);
}
_selectEndDate(BuildContext context) async {
final newDate = await showDatePicker(
context: context,
initialDate: selectedEndDate,
firstDate: DateTime(2010),
lastDate: DateTime(2025),
);
if (newDate == null) return;
setState(() => endDate = newDate);
}
Iterable<Widget> get statusPosition sync* {
for (FilterWidget company in _status) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
avatar: CircleAvatar(
backgroundColor: Colors.cyan,
child: Text(
company.name[0].toUpperCase(),
style: TextStyle(color: Colors.white),
),
),
label: Text(
company.name,
style: TextStyle(
color: _isSelected == false ? Colors.grey : Colors.white,
fontFamily: "Roboto",
),
),
selected: _statusFilters.contains(company.name),
checkmarkColor: Colors.white,
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_statusFilters.add(company.name);
} else {
_statusFilters.removeWhere((String name) {
return name == company.name;
});
}
print(_statusFilters.toString());
});
},
),
);
}
}
Iterable<Widget> get projectCodePosition sync* {
for (FilterWidget company in _projectCode) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
label: Text(
company.name,
style: TextStyle(
color: _isSelected == false ? Colors.grey : Colors.white,
fontFamily: "Roboto",
),
),
selected: _projectCodeFilters.contains(company.name),
checkmarkColor: Colors.white,
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_projectCodeFilters.add(company.name);
activateButton = true;
} else {
_projectCodeFilters.removeWhere((String name) {
print("hi length is ${_projectCodeFilters.length}");
if (_projectCodeFilters.length == 1) activateButton = false;
return name == company.name;
});
}
print(_projectCodeFilters.toString());
});
},
),
);
}
}
Iterable<Widget> get laborPosition sync* {
for (FilterWidget company in _labor) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
backgroundColor: Colors.white60,
shape: StadiumBorder(
side: BorderSide(color: Colors.grey, width: 0.5),
),
avatar: CircleAvatar(
backgroundColor: Colors.cyan,
child: Text(
company.name[0].toUpperCase(),
style: TextStyle(color: Colors.white),
),
),
label: Text(
company.name,
style: TextStyle(
color: Colors.grey,
fontFamily: "Roboto",
),
),
selected: _laborFilters.contains(company.name),
selectedColor: Color(0xFF023E8A),
onSelected: (bool selected) {
setState(() {
if (selected) {
_laborFilters.add(company.name);
} else {
_laborFilters.removeWhere((String name) {
return name == company.name;
});
}
print(_laborFilters.toString());
});
},
),
);
}
}
}
class FilterWidget {
const FilterWidget(this.name);
final String name;
}
CodePudding user response:
To disable a button in Flutter, pass in null
to the onPressed
argument.
onPressed: (some_condition is true) ? () {...} : null,