Related
Am trying to select one or more check boxes from a list of check boxes, i have found that the best option is using the checkBoxListTile widget to implement this.
First i have defined a list and used the widget as follows:
List<String> _texts = ["google.com", "youtube.com", "yahoo.com", "gmail.com"];
Expanded(
child: ListView(
children: _texts
.map((text) => CheckboxListTile(
title: Text(text),
value: _isChecked,
onChanged: (val) {
setState(() {
_isChecked = val;
});
},
))
.toList(),
),
),
check boxes are displayed fine but whenever i click one checkbox all are checked, how can i handle choosing one or more check boxes from the list?
Thank you
Try below code hope its help to you I have try it other way
Only Single Checkbox Selected:
Your List :
List _texts = [
{
"value": false,
"site": "google.com",
},
{
"value": false,
"site": "youtube.com",
},
{
"value": false,
"site": "yahoo.com",
},
{
"value": false,
"site": "gmail.com",
},
];
Your Widget:
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
child: Column(
children: List.generate(
_texts.length,
(index) => CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(
_texts[index]["site"],
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
),
),
value: _texts[index]["value"],
onChanged: (value) {
setState(() {
for (var element in _texts) {
element["value"] = false;
}
_texts[index]["value"] = value;
});
},
),
),
),
),
Full Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Flutter Single Checkbox Example"),
),
body: SafeArea(
child: Center(
child: CheckboxWidget(),
))),
);
}
}
class CheckboxWidget extends StatefulWidget {
#override
CheckboxWidgetState createState() => new CheckboxWidgetState();
}
class CheckboxWidgetState extends State {
List _texts = [
{
"value": false,
"site": "google.com",
},
{
"value": false,
"site": "youtube.com",
},
{
"value": false,
"site": "yahoo.com",
},
{
"value": false,
"site": "gmail.com",
},
];
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
child: Column(
children: List.generate(
_texts.length,
(index) => CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(
_texts[index]["site"],
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
),
),
value: _texts[index]["value"],
onChanged: (value) {
setState(() {
for (var element in _texts) {
element["value"] = false;
}
_texts[index]["value"] = value;
});
},
),
),
),
);
}
}
Result Screen->
Multiple Checkbox Selection
Your List/Map
Map<String, bool> values = {
'google.com': false,
'youtube.com': false,
'yahoo.com': false,
'gmail.com': false,
};
Your Function:
var tmpArray = [];
getCheckboxItems() {
values.forEach((key, value) {
if (value == true) {
tmpArray.add(key);
}
});
print(tmpArray);
tmpArray.clear();
}
Your Widget:
Column(
children: <Widget>[
ListView(
shrinkWrap: true,
children: values.keys.map((String key) {
return new CheckboxListTile(
title: new Text(key),
value: values[key],
onChanged: (value) {
setState(() {
values[key] = value!;
});
},
);
}).toList(),
),
const SizedBox(
height: 100,
),
ElevatedButton(
child: Text(
" Checkbox Items ",
style: TextStyle(fontSize: 18),
),
onPressed: getCheckboxItems,
),
],
)
Full Example
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Flutter Multiple Checkbox Example"),
),
body: SafeArea(
child: Center(
child: CheckboxWidget(),
))),
);
}
}
class CheckboxWidget extends StatefulWidget {
#override
CheckboxWidgetState createState() => new CheckboxWidgetState();
}
class CheckboxWidgetState extends State {
Map<String, bool> values = {
'google.com': false,
'youtube.com': false,
'yahoo.com': false,
'gmail.com': false,
};
var tmpArray = [];
getCheckboxItems() {
values.forEach((key, value) {
if (value == true) {
tmpArray.add(key);
}
});
print(tmpArray);
tmpArray.clear();
}
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListView(
shrinkWrap: true,
children: values.keys.map((String key) {
return new CheckboxListTile(
title: new Text(key),
value: values[key],
onChanged: (value) {
setState(() {
values[key] = value!;
});
},
);
}).toList(),
),
const SizedBox(
height: 100,
),
ElevatedButton(
child: Text(
" Checkbox Items ",
style: TextStyle(fontSize: 18),
),
onPressed: getCheckboxItems,
),
],
);
}
}
Result Screen->
Refer Video Tutorial for Flutter Multiselect Dropdown Checkbox on YouTube
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: _title,
home: CheckBoxExample(),
);
}
}
class CheckBoxExample extends StatefulWidget {
const CheckBoxExample({Key? key}) : super(key: key);
#override
State<CheckBoxExample> createState() => _CheckBoxExampleState();
}
class _CheckBoxExampleState extends State<CheckBoxExample> {
String selectedMonth = "";
List checkListItems = [
{
"id": 0,
"value": false,
"monthName": "January",
},
{
"id": 1,
"value": false,
"monthName": "Febuary",
},
{
"id": 2,
"value": false,
"monthName": "March",
},
{
"id": 3,
"value": false,
"monthName": "April",
},
{
"id": 4,
"value": false,
"monthName": "May",
},
{
"id": 5,
"value": false,
"monthName": "June",
},
{
"id": 6,
"value": false,
"monthName": "July",
},
{
"id": 7,
"value": false,
"monthName": "August",
},
{
"id": 8,
"value": false,
"monthName": "September",
},
{
"id": 9,
"value": false,
"monthName": "October",
},
{
"id": 10,
"value": false,
"monthName": "November",
},
{
"id": 11,
"value": false,
"monthName": "December",
},
];
#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: [
Text(
selectedMonth,
style: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 85.0),
Column(
children: List.generate(
checkListItems.length,
(index) => CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text(
checkListItems[index]["monthName"],
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
),
),
value: checkListItems[index]["value"],
onChanged: (value) {
setState(() {
for (var element in checkListItems) {
element["value"] = false;
}
checkListItems[index]["value"] = value;
selectedMonth ="${checkListItems[index]["id"]+1}, ${checkListItems[index]["monthName"]}";
});
},
),
),
),
],
),
),
);
}
}
Output
The value parameter for in CheckboxListTile is how widget knows whether checkbox is checked or not. When you give all of them same value, all of their state changes.
You can keep a seperate list to keep track of if the specific checkbox is checked.
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,
),
),
],
),
),
);
}
}
I have shopping app want to create Wishlist ,I did many things correctly,just when I want to check one product all products checked ,also when I want increase or decrease number of product all products quantity change as shown in image below ,my code :
Provider :
class ProductProvider with ChangeNotifier {
List<Product> products = [];
bool isAdded = false;
int count = 0;
void chane_add_color() {
isAdded = !isAdded;
notifyListeners();
}
void add_count() {
count++;
notifyListeners();
}
void rem_count() {
if (count > 0) {
count--;
}
notifyListeners();
}
}
my list tile left trailing :
trailing: Consumer<ProductProvider>(
builder: (context, prod, child) {
return Wrap(
spacing: 35,
children: <Widget>[
Column(
children: [
InkWell(
onTap: prod.add_count,
child: Icon(Icons.add, color: Colors.green)),
Text('${prod.count}'),
InkWell(
onTap: prod.rem_count,
child: Icon(Icons.remove, color: Colors.red)),
],
),
IconButton(
onPressed: prod.chane_add_color,
icon: Icon(Icons.favorite,
color: prod.isAdded ? Colors.red : Colors.grey),
),
],
);
}),
the result :
I guess it need a list for counter ,but don't know how to do
is there any suggestion ?
This is notifier class:
class ProductModel extends ChangeNotifier {
List<Map<String, dynamic>> _products = [
{'product': 'mercedes', 'count': 0, 'isFavorite': false},
{'product': 'audi', 'count': 0, 'isFavorite': false},
{'product': 'bmw', 'count': 0, 'isFavorite': false},
{'product': 'volvo', 'count': 0, 'isFavorite': false}
];
List<Map<String, dynamic>> get products => _products;
ProductModel();
ProductModel.instance();
addFavorite({int index}) {
_products[index]['isFavorite'] = !_products[index]['isFavorite'];
notifyListeners();
}
incrementCounter({int index}) {
_products[index]['count'] += 1;
notifyListeners();
}
}
This is your widget:
class ProductView extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider<ProductModel>(
create: (context) => ProductModel.instance(),
child: Consumer<ProductModel>(
builder: (context, viewModel, child) {
return ListView.builder(
itemCount: viewModel.products.length,
itemBuilder: (context, index) {
return ListTile(
leading: FlatButton(
child: Text('${viewModel.products[index]['count']} +'),
onPressed: () {
viewModel.incrementCounter(index: index);
},
),
title: Text(viewModel.products[index]['product']),
trailing: IconButton(
icon: Icon(
Icons.favorite,
color: viewModel.products[index]['isFavorite']
? Colors.red
: Colors.grey,
),
onPressed: () {
viewModel.addFavorite(index: index);
},
),
);
},
);
},
),
),
);
}
}
I wish to print the quantity of the items selected but am not able to do so. I am using providers to access data but it's showing some error. The same method worked when I applied it elsewhere but it doesn't seem to work here Please help.
Snippet for the type of data I receive:
{
"delivery_status": true,
"coupon_code": null,
"cart": [
{
"food_item_id": "2c7289c1-17fb-4f3a-90af-7a014e051c53",
"name": "Grape",
"price": 35.0,
"category": "Fresh Fruit Juice",
"available": true,
"veg": false,
"egg": false,
"restaurant": "9adafbd7-a9ba-4890-b707-c9d619c72f02",
"quantity": 1
},
{
"food_item_id": "be303557-90ce-4f9c-a30f-5a6d650977b6",
"name": "Mix Juice",
"price": 35.0,
"category": "Fresh Fruit Juice",
"available": true,
"veg": false,
"egg": false,
"restaurant": "9adafbd7-a9ba-4890-b707-c9d619c72f02",
"quantity": 2
},
{
"food_item_id": "13fb9de8-c774-4f6d-af66-74cc6dedbf14",
"name": "Boondi Raita",
"price": 110.0,
"category": "Salad Bar",
"available": true,
"veg": false,
"egg": false,
"restaurant": "9adafbd7-a9ba-4890-b707-c9d619c72f02",
"quantity": 1
}
],
"total_amount": 215.0
}
Snippet for Mapping Logic:
CartItem _items = CartItem(
couponCode: '',
deliveryStatus: false,
totalAmount: 0.0,
);
CartItem get items {
return _items;
}
// ===============================Looks Here
List<MenuItem> _cartProducts = [];
List<MenuItem> get cartProducts {
return [..._cartProducts];
}
Future<void> getCart() async {
Map<String, String> header = {
'Content-type': 'application/json',
'Authorization': accessToken,
};
try {
final response = await http.get(apiURL + getCartURL, headers: header);
print(response.statusCode);
if (response.statusCode == 200) {
final res = jsonDecode(response.body) as Map<String, dynamic>;
if (res == null) {
return _items;
}
_items = CartItem(
deliveryStatus: res['delivery_status'],
couponCode: res['coupon_code'],
totalAmount: res['total_amount'],
);
// ===============================Looks Here
List<MenuItem> cartStuff = [];
res["cart"].forEach((cartData) {
cartStuff.add(
MenuItem(
foodItemId: cartData['food_item_id'],
category: cartData['category'],
name: cartData['name'],
isAvailable: cartData['available'],
isEgg: cartData['egg'],
isVeg: cartData['veg'],
price: cartData['price'],
restaurant: cartData['restaurant'],
quantity: cartData['quantity'],
),
);
});
// ===============================Looks Here
_cartProducts = cartStuff;
print(_cartProducts);
notifyListeners();
} else if (response.statusCode == 403) {
fetchNewAToken().then((_) {
if (accessToken != null && refreshToken != null) getCart();
notifyListeners();
});
}
} catch (e) {
print("Error in getting the Cart");
print(e);
}
}
Snippet for displaying the data:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../globals/text_styles.dart';
import '../../globals/colors.dart';
import '../../providers/cart.dart';
class QuantityButton extends StatefulWidget {
//The item id received is correct so the error occurs is in accessing the data from the provider.
final itemID;
QuantityButton(this.itemID);
#override
_QuantityButtonState createState() => _QuantityButtonState();
}
class _QuantityButtonState extends State<QuantityButton> {
#override
Widget build(BuildContext context) {
final cartData = Provider.of<Cart>(context);
final cartQty =
cartData.cartProducts.where((item) => item.foodItemId == widget.itemID);
return Container(
width: 100,
height: 40,
child: Card(
color: primaryColor.withOpacity(0.9),
elevation: 0,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.black),
borderRadius: BorderRadius.circular(10),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
cartData.deleteItems(widget.itemID);
},
child: Icon(
Icons.arrow_left,
color: Colors.white,
size: 25,
),
),
Spacer(),
Container(
child: Padding(
padding: const EdgeInsets.all(3.0),
child: Text(
// =========== Print Quantity Here ===========
'',
style: valueTextStyle,
),
),
),
Spacer(),
GestureDetector(
onTap: () {
cartData.addItems(widget.itemID);
},
child: Icon(
Icons.arrow_right,
color: Colors.white,
size: 25,
),
),
],
),
),
);
}
}
I have a 3 check box in my app, which are formed by looping over the tickbox map, in my Application it allows to select multiple checkboxes but I dont want that to happen , only one should be selected at a time, is there any way to do so in flutter.
below is my code.
class _DashboardFilterState extends State<DashboardFilter> {
void showModalSheet() {
List<Map<String, Object>> tickbox;
timeData = [
{"id": "1", "displayId": "Daily"},
{"id": "2", "displayId": "Weekly"},
{"id": "3", "displayId": "Monthly"}
];
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter state) {
return createBox(context, timeData, state);
});
});
}
createBox(BuildContext context,List<Map<String, Object>> tickbox, StateSetter state) {
var tickboxdata = tickbox.map<Widget>((data) {
int id = data["id"];
var dispId = data["displayId"];
return buildTimeData(context, id, dispId, state);
}).toList();
return SingleChildScrollView(
child: LimitedBox(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
// children: metrics,
children: <Widget>[
Container(
child: Column(
children: tickboxdata,
),
),
],
)),
);
}
Widget buildTimeData(
BuildContext context, var id, var disp, StateSetter state) {
return Container(
child: Column(mainAxisSize: MainAxisSize.min,
children: <Widget>[
CheckboxListTile(
value: widget.timeSelected[id],
title: Text(disp),
controlAffinity: ListTileControlAffinity.leading,
onChanged: (bool val) {
manageTimeState(val, id, state);
})
]));
}
void manageTimeState(bool val, var id, StateSetter state) {
state(() {
widget.timeSelected[id] = val;
});
}
let me know if is there any other option to do so thanks
without any package i make the example (null safe)
Output :-
Example 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> {
String selected = "";
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: [
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(() {
for (var element in checkListItems) {
element["value"] = false;
}
checkListItems[index]["value"] = value;
selected =
"${checkListItems[index]["id"]}, ${checkListItems[index]["title"]}, ${checkListItems[index]["value"]}";
});
},
),
),
),
const SizedBox(height: 100.0),
Text(
selected,
style: const TextStyle(
fontSize: 22.0,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}
please use package https://pub.dev/packages/grouped_buttons
In onSelected, remove first selected item if more than one selected
code snippet
List<String> _checked = [];
...
CheckboxGroup(
labels: <String>[
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
disabled: ["Wednesday", "Friday"],
checked: _checked,
onChange: (bool isChecked, String label, int index) =>
print("isChecked: $isChecked label: $label index: $index"),
onSelected: (List selected) => setState(() {
if (selected.length > 1) {
selected.removeAt(0);
print('selected length ${selected.length}');
} else {
print("only one");
}
_checked = selected;
}),
),
full code
/*
Name: Akshath Jain
Date: 3/15/19
Purpose: example app for the grouped buttons package
*/
import 'package:flutter/material.dart';
import 'package:grouped_buttons/grouped_buttons.dart';
void main() => runApp(GroupedButtonExample());
class GroupedButtonExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Grouped Buttons Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<String> _checked = []; //["A", "B"];
String _picked = "Two";
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Grouped Buttons Example"),
),
body: _body(),
);
//
}
Widget _body() {
return ListView(children: <Widget>[
//--------------------
//SIMPLE USAGE EXAMPLE
//--------------------
//BASIC CHECKBOXGROUP
Container(
padding: const EdgeInsets.only(left: 14.0, top: 14.0),
child: Text(
"Basic CheckboxGroup",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
),
CheckboxGroup(
labels: <String>[
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
disabled: ["Wednesday", "Friday"],
checked: _checked,
onChange: (bool isChecked, String label, int index) =>
print("isChecked: $isChecked label: $label index: $index"),
onSelected: (List selected) => setState(() {
if (selected.length > 1) {
selected.removeAt(0);
print('selected length ${selected.length}');
} else {
print("only one");
}
_checked = selected;
}),
),
//BASIC RADIOBUTTONGROUP
Container(
padding: const EdgeInsets.only(left: 14.0, top: 14.0),
child: Text(
"Basic RadioButtonGroup",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
),
RadioButtonGroup(
labels: [
"Option 1",
"Option 2",
],
disabled: ["Option 1"],
onChange: (String label, int index) =>
print("label: $label index: $index"),
onSelected: (String label) => print(label),
),
//--------------------
//CUSTOM USAGE EXAMPLE
//--------------------
///CUSTOM CHECKBOX GROUP
Container(
padding: const EdgeInsets.only(left: 14.0, top: 14.0, bottom: 14.0),
child: Text(
"Custom CheckboxGroup",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
),
CheckboxGroup(
orientation: GroupedButtonsOrientation.HORIZONTAL,
margin: const EdgeInsets.only(left: 12.0),
onSelected: (List selected) => setState(() {
_checked = selected;
}),
labels: <String>[
"A",
"B",
],
checked: _checked,
itemBuilder: (Checkbox cb, Text txt, int i) {
return Column(
children: <Widget>[
Icon(Icons.polymer),
cb,
txt,
],
);
},
),
///CUSTOM RADIOBUTTON GROUP
Container(
padding: const EdgeInsets.only(left: 14.0, top: 14.0, bottom: 14.0),
child: Text(
"Custom RadioButtonGroup",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
),
),
RadioButtonGroup(
orientation: GroupedButtonsOrientation.HORIZONTAL,
margin: const EdgeInsets.only(left: 12.0),
onSelected: (String selected) => setState(() {
_picked = selected;
}),
labels: <String>[
"One",
"Two",
],
picked: _picked,
itemBuilder: (Radio rb, Text txt, int i) {
return Column(
children: <Widget>[
Icon(Icons.public),
rb,
txt,
],
);
},
),
]);
}
}
working demo