Textfield filter in Flutter - flutter

I'm a total beginner in Flutter. I try to integrate a textfield filter for my table, but the table is not filtered, but remains unchanged. I added a Provider because I need the current table of Students. after that the Table can't be filtered anymore. Can anyone help me?
here is my code:
class ResultPage extends StatefulWidget {
const ResultPage({Key? key}) : super(key: key);
#override
State<ResultPage> createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
List<User>? myData = [];
List<User>? filterData;
_getData(BuildContext context){
myData = Provider.of<LoginService>(context).getStudentsList();
filterData = Provider.of<LoginService>(context).getStudentsList();
}
bool sort = true;
#override
void initState() {
filterData = myData;
super.initState();
}
TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
_getData(context);
return Scaffold(
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
child: Theme(
data: ThemeData.light()
.copyWith(cardColor: Theme.of(context).canvasColor),
child: PaginatedDataTable(
sortColumnIndex: 0,
sortAscending: sort,
header: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(12)),
child: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: "Enter name to filter"),
onChanged: (value) {
setState(() {
myData = filterData!
.where(
(element) => element.getName.contains(value))
.toList();
});
},
onSubmitted: (value) {
setState(() {
FocusScope.of(context).unfocus();
});
},
),
),
source: RowSource(
myData: myData,
count: myData!.length,
),
rowsPerPage: 16,
columnSpacing: 8,
columns: const [
DataColumn(
label: Text(
"Schüler",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
DataColumn(
label: Text(
"Anzahl Spiele",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
DataColumn(
label: Text(
"Score",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
],
),
)),
const SizedBox(height: 20),
],
),
)
);
}
}
class RowSource extends DataTableSource {
var myData;
final count;
RowSource({
required this.myData,
required this.count,
});
#override
DataRow? getRow(int index) {
if (index < rowCount) {
return recentFileDataRow(myData![index]);
} else {
return null;
}
}
#override
bool get isRowCountApproximate => false;
#override
int get rowCount => count;
#override
int get selectedRowCount => 0;
}
DataRow recentFileDataRow(User data) {
return DataRow(
cells: [
DataCell(Text(data.getName)),
DataCell(Text(data.getSolvedGames().toString())),
DataCell(Text(data.getScore().toString())),
],
);
}
With my code the table always remains unchanged.

Related

Not Showing Data from Api In DataTable

hi i have json like this:
"data": {
"list_item": [
{
"item": "1",
"item_date": "1669189813143566825",
"item_id": "0",
"item_info": {},"
"item_status":"on",
}]}
this class with sample table worked for me!but my table in app used paginated table and not worked in.
class TableSamleNew extends StatefulWidget {
const TableSamleNew({Key? key}) : super(key: key);
#override
State<TableSamleNew> createState() => _TableSamleNewState();
}
class _TableSamleNewState extends State<TableSamleNew> {
final getListController = Get.put(GetListController());
late List<ListItem>? listItem=getListController.getListClient!.data!.listItem;
#override
Widget build(BuildContext context) {
return Scaffold(
body: GetBuilder<GetListController>(
builder: (_) => getListController.isLoading
? const Padding(
padding: EdgeInsets.only(top:50),
child: Center(child: CircularProgressIndicator()),
): DataTable(columns: [
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1"))
],rows: listItem!.map<DataRow>((e) => DataRow(cells: [
DataCell(Text(e.itemInfo!.clientMobile.toString())),
DataCell(Text(e.itemId.toString())),
DataCell(Text(e.itemId.toString())),
DataCell(Text("")),
DataCell(Text("")),
])).toList()),
),
);
}
}
this is my main table and not showing data..
table with paginated and sort data and search with one field in table but output showing me null
class DataTableWithSortTest extends StatefulWidget {
const DataTableWithSortTest({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<DataTableWithSortTest> createState() => _DataTableWithSortTestState();
}
class _DataTableWithSortTestState extends State<DataTableWithSortTest> {
final getListController = Get.put(GetListController());
late List<ListItem>? listItem=getListController.getListClient!.data!.listItem;
bool sort = true;
onsortColum(int columnIndex, bool ascending) {
if (columnIndex == 0) {
if (ascending) {
listItem!.sort((a, b) => a.itemStatus!.compareTo(b.itemStatus!));
} else {
listItem!.sort((a, b) => b.itemStatus!.compareTo(a.itemStatus!));
}
}
}
#override
void initState() {
listItem = listItem!.cast<ListItem>();
super.initState();
}
TextEditingController controller = TextEditingController();
#override
Widget build(BuildContext context) {
print(listItem);
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
body: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: double.infinity,
child: Theme(
data: ThemeData.light()
.copyWith(cardColor: Theme.of(context).canvasColor),
child: PaginatedDataTable(
sortColumnIndex: 0,
sortAscending: sort,
header: Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
),
borderRadius: BorderRadius.circular(12)),
child: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: "search with name"),
onChanged: (value) {
setState(() {
listItem = listItem!
.where((element) =>
element.itemStatus!.contains(value))
.toList();
});
},
),
),
source: RowSource(
listItem: listItem,
count: listItem?.length,
),
rowsPerPage: 5,
columnSpacing: 5,
columns: [
DataColumn(
label: const Text(
"1",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
onSort: (columnIndex, ascending) {
setState(() {
sort = !sort;
});
// onsortColum(columnIndex, ascending);
}),
const DataColumn(//
label: Text(
"2",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
const DataColumn(
label: Text(
"3",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
const DataColumn(
label: Text(
"4",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
const DataColumn(
label: Text(
"5",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 14),
),
),
],
),
)),
const SizedBox(height: 20),
],
),
),
)),
);
}
}
class RowSource extends DataTableSource {
var listItem;
final count;
RowSource({
required this.listItem,
required this.count,
});
#override
DataRow? getRow(int index) {
if (index < rowCount) {
return recentFileDataRow(listItem![index]);
} else
return null;
}
#override
bool get isRowCountApproximate => false;
#override
int get rowCount => count;
#override
int get selectedRowCount => 0;
}
DataRow recentFileDataRow(var listItem) {
return const DataRow(
cells: [
DataCell(Text("")),
DataCell(Text("")),
DataCell(Text("")),
DataCell(Text("")),
DataCell(Text("")),
],
);
}
You need to define these variable out of build methode:
late List<ListItem>? listItem =getListController.getListClient!.data!.listItem;
every time the widget rebuild you variable redefine and became empty.
class TableSamleNew extends StatefulWidget {
const TableSamleNew({Key? key}) : super(key: key);
#override
State<TableSamleNew> createState() => _TableSamleNewState();
}
class _TableSamleNewState extends State<TableSamleNew> {
final getListController = Get.put(GetListController());
ValueNotifier<List<ListItem>> listItemNotifier = ValueNotifier([]);
#override
Widget build(BuildContext context) {
listItemNotifier.value=getListController.getListClient!.data!.listItem;
return Scaffold(
body: ValueListenableBuilder(
valueListenable: listItemNotifier,
builder:(context,List<ListItem> items, child) =>
DataTable(columns: [
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1")),
DataColumn(label: Text("1"))
],rows: items.map<DataRow>((e) => DataRow(cells: [
DataCell(Text(e.itemId.toString())),
DataCell(Text(e.itemId.toString())),
DataCell(Text(e.itemId.toString())),
DataCell(Text(e.itemId.toString())),
DataCell(Text(e.itemId.toString())),
])).toList()),
);
);
}
}
try to use ValueNotifier

The value entered in TextField is inherited

I'm developing a fill-in-the-blanks quiz app.
There are 5 question statements in one quiz, but when I move on to the next question statement, the value entered in the text field remains. Could you please tell me what are the possible causes?
class PlayGame extends StatefulWidget {
final List document;
List correctList = [];
PlayGame({Key? key, required this.document}) : super(key: key);
#override
State<PlayGame> createState() => _PlayGameState();
}
class _PlayGameState extends State<PlayGame> {
int quizNum = 0;
int quizCount = 1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Center(
child: Text(
"$quizCount/5",
style: const TextStyle(
fontSize: 25,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold),
),
),
actions: [
Row(
children: [
IconButton(
onPressed: () {
setState(
() {
if (quizNum < 4) {
quizNum += 1;
quizCount += 1;
} else if (quizNum == 4) {
print(widget.correctList.length);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Result()),
);
}
},
);
},
icon: const Icon(
Icons.arrow_circle_right_outlined,
size: 40,
),
),
const SizedBox(
width: 10,
)
],
)
],
automaticallyImplyLeading: false,
),
body: SizedBox(
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: TextWithBlanks(
text: widget.document[quizNum],
correctList: widget.correctList),
),
),
),
);
}
}
This is the code I was taught here. Words surrounded by "{}" are BlankWord.
class TextWithBlanks extends StatefulWidget {
final String text;
static final regex = RegExp("(?={)|(?<=})");
List correctList = [];
TextWithBlanks({Key? key, required this.text, required this.correctList})
: super(key: key);
#override
State<TextWithBlanks> createState() => _TextWithBlanksState();
}
class _TextWithBlanksState extends State<TextWithBlanks> {
#override
Widget build(BuildContext context) {
final split = widget.text.split(TextWithBlanks.regex);
return Padding(
padding: const EdgeInsets.only(top: 30.0, right: 30.0, left: 30.0),
child: Text.rich(
TextSpan(
style: const TextStyle(fontSize: 15, height: 3.0),
children: <InlineSpan>[
for (String text in split)
text.startsWith('{')
? WidgetSpan(
child: blankWord(text.substring(1, text.length - 1),
widget.correctList),
)
: TextSpan(text: text),
],
),
),
);
}
}
This is the BlankWord.
class _blankWordState extends State<blankWord> {
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget.answerWidth,
child: TextField(
maxLines: null,
cursorColor: Colors.grey,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
autofocus: false,
maxLength: widget.answerLength + 5,
onChanged: (enterWord) {
widget.value = enterWord;
if (enterWord == widget.answer) {
if (widget.answerBool == false) {
widget.answerBool = true;
widget.correctList.add(widget.answer);
}
} else {
if (widget.answerBool == true) {
widget.answerBool = false;
widget.correctList.remove(widget.answer);
}
}
},
decoration: InputDecoration(
counterText: "",
hintText: widget.answerHint,
hintStyle: const TextStyle(color: Colors.grey, fontSize: 12),
),
),
);
}
}
When you update the page by changing the quiz number also reset the value that you are sending to the blank widget. When the blank widget is updated the widget.value is being updated, and that value stays in the class and when a new blank widget is added the value is being sent to the blank widget again I think
widget.value = enterWord;

Search Result does not update instantly flutter

I'm emulating this search and filter github here and the codes are almost the same but the filtered results do not update instantly while I type and also I faced the following issues:
I will have to press enter on my laptop to finally get the filtered list
When I hit the close icon(which is to clear all the words), I will have to tap the searchbar again so that all my listtile are back on the listview.
Here's my code:
class _CurrencySelectState extends State<CurrencySelect> {
late List<Currency> resCur;
String query = '';
#override
void initState() {
super.initState();
resCur = currencyList;
}
void searchCur(String query) {
final List<Currency> filteredCur = currencyList.where((cur) {
final symbolLower = cur.symbol.toLowerCase(); // Search using symbol
final nameLower = cur.country.toLowerCase(); // Search using country
final searchLower = query.toLowerCase();
return symbolLower.contains(searchLower) ||
nameLower.contains(searchLower);
}).toList();
setState(() {
this.query = query;
resCur = filteredCur;
});
}
#override
Widget build(BuildContext context) {
Widget buildCur(Currency cur) => ListTile(
leading: Padding(
padding: EdgeInset.all(5)
child: SizedBox(
child: Column(
children: <Widget>[
SvgPicture.asset(
cur.assetPath,
),
]),
),
),
title: Column(
children: [
Text(
cur.symbol,
style: TextStyle(
...
),
Text(
cur.name,
style: TextStyle(
...
),
],
),
trailing: Text(
"0.25",
style: TextStyle(
...
),
);
return TextButton(
onPressed: () async {
showModalBottomSheet(
enableDrag: false,
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return DraggableScrollableSheet(
expand: false,
builder: (context, scrollController) {
return Column(
children: <Widget>[
SearchWidget(
text: query,
onChanged: searchCur,
hintText: "Enter symbol or country"
),
Expanded(
child: ListView.builder(
controller: scrollController,
itemCount: resCur.length,
itemBuilder: (context, int index) {
final cur = resCur[index];
return buildCur(cur);
},
),
)
],
);
},
);
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text(
...
),
SvgPicture.asset(
...
)
],
));
}
}
Searchwidget code:
import 'package:flutter/material.dart';
class SearchWidget extends StatefulWidget {
final String text;
final ValueChanged<String> onChanged;
final String hintText;
const SearchWidget({
Key? key,
required this.text,
required this.onChanged,
required this.hintText,
}) : super(key: key);
#override
_SearchWidgetState createState() => _SearchWidgetState();
}
class _SearchWidgetState extends State<SearchWidget> {
final controller = TextEditingController();
#override
Widget build(BuildContext context) {
final styleActive = TextStyle(color: Colors.black);
final styleHint = TextStyle(color: Colors.black54);
final style = widget.text.isEmpty ? styleHint : styleActive;
return Container(
height: 42,
margin: const EdgeInsets.fromLTRB(16, 16, 16, 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
border: Border.all(color: Colors.black26),
),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: TextField(
controller: controller,
decoration: InputDecoration(
icon: Icon(Icons.search, color: style.color),
suffixIcon: widget.text.isNotEmpty
? GestureDetector(
child: Icon(Icons.close, color: style.color),
onTap: () {
controller.clear();
widget.onChanged('');
FocusScope.of(context).requestFocus(FocusNode());
},
)
: null,
hintText: widget.hintText,
hintStyle: style,
border: InputBorder.none,
),
style: style,
onChanged: widget.onChanged,
),
);
}
}

Checkbox doesn't change when clicked in dropdownbutton

I am using DropdownButton and I am facing the following issue. I'm using a checkbox in elements, but when I click on an element, I don't get a checkmark indicating that the checkbox has been clicked. As a result, I need to close and reopen it, and then I will see the changes that were clicked on the "checkbox". The second problem is that when I select one element, all elements are selected for me. As a final result, I need to get so that I can select an element and the checkbox is immediately marked, if 2 elements are needed, then two, and so on. Tell me how to fix these problems, I will be grateful for the help?
dropdown
class DropdownWidget extends StatefulWidget {
List<String> items;
SvgPicture? icon;
double width;
DropdownWidget({
Key? key,
required this.items,
required this.icon,
required this.width,
}) : super(key: key);
#override
State<DropdownWidget> createState() => _DropdownWidgetState();
}
class _DropdownWidgetState extends State<DropdownWidget> {
String? selectedValue;
bool isChecked = false;
#override
void initState() {
super.initState();
if (widget.items.isNotEmpty) {
selectedValue = widget.items[1];
}
}
#override
Widget build(BuildContext context) {
return SizedBox(
width: widget.width,
child: DropdownButtonHideUnderline(
child: DropdownButton2(
items: widget.items
.map((item) => DropdownMenuItem<String>(
value: item,
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: constants.Colors.white.withOpacity(0.1),
width: 1,
),
),
),
child: Center(
child: Row(
children: [
if (item == selectedValue)
const SizedBox(
width: 0,
),
Expanded(
child: Text(
item,
style: constants.Styles.smallTextStyleWhite,
),
),
Checkbox(
checkColor: Colors.black,
value: isChecked,
onChanged: (bool? value) {
setState(() {
isChecked = value!;
});
},
),
],
),
),
),
))
.toList(),
value: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value as String;
});
},
icon: SvgPicture.asset(constants.Assets.arrowDropdown),
iconSize: 21,
buttonHeight: 27,
itemHeight: 47,
dropdownMaxHeight: 191,
dropdownWidth: 140,
dropdownDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: constants.Colors.purpleMain,
),
color: constants.Colors.greyDark,
),
selectedItemBuilder: (context) {
return widget.items.map(
(item) {
return Row(
children: [
widget.icon ?? const SizedBox(),
const SizedBox(width: 8),
Text(
item,
style: constants.Styles.bigBookTextStyleWhite,
),
],
);
},
).toList();
},
),
),
);
}
}
items
final List<String> items = const [
"All EV's",
'Main EV',
'<EV2>',
];
I hope this example explains the concept. For simplcity I made simple a new file, run it and see the results:
Then main idea in two lists, _checkList contain values of the CheckBox and _selectedList handles the main dropdown widget to show the selection.
Feel free to ask any questions and I'm happy to help
import 'package:flutter/material.dart';
class TestPage extends StatelessWidget {
const TestPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const AnimationDemo(number: 5);
}
}
class AnimationDemo extends StatefulWidget {
const AnimationDemo({Key? key, this.number = 2}) : super(key: key);
final int number;
#override
State<AnimationDemo> createState() => _AnimationDemoState();
}
class _AnimationDemoState extends State<AnimationDemo> {
late List<bool> _checkList;
late List<int> _selectedIndex;
bool _isOpen = false;
#override
void initState() {
_checkList = List.filled(widget.number, false);
_selectedIndex = <int>[];
super.initState();
}
List<DropDownItem> generateItems() {
var tmp = <DropDownItem>[];
for (var i = 0; i < _checkList.length; i++) {
tmp.add(DropDownItem(
isChecked: _checkList[i],
onChanged: (value) {
setState(() {
_checkList[i] = value!;
if (value && !_selectedIndex.contains(i)) {
_selectedIndex.add(i);
} else {
_selectedIndex.remove(i);
}
});
},
));
}
return tmp;
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: Text((_selectedIndex.isEmpty)
? 'Nothing Selected'
: _selectedIndex.join(',')),
),
GestureDetector(
onTap: () {
setState(() {
_isOpen = !_isOpen;
});
},
child: const Icon(Icons.arrow_downward),
),
],
),
AnimatedOpacity(
opacity: (_isOpen) ? 1 : 0,
duration: const Duration(milliseconds: 300),
child: Column(
mainAxisSize: MainAxisSize.min,
children: generateItems(),
),
)
],
),
);
}
}
class DropDownItem extends StatelessWidget {
final bool isChecked;
final Function(bool?)? onChanged;
const DropDownItem({Key? key, this.onChanged, this.isChecked = false})
: super(key: key);
#override
Widget build(BuildContext context) {
return Row(
children: [
const Expanded(child: Text('Demo item')),
Checkbox(value: isChecked, onChanged: onChanged)
],
);
}
}
Here's how to achieve the Multiselect dropdown with DropdownButton2:
final List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
];
List<String> selectedItems = [];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
isExpanded: true,
hint: Align(
alignment: AlignmentDirectional.center,
child: Text(
'Select Items',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
),
items: items.map((item) {
return DropdownMenuItem<String>(
value: item,
//disable default onTap to avoid closing menu when selecting an item
enabled: false,
child: StatefulBuilder(
builder: (context, menuSetState) {
final _isSelected = selectedItems.contains(item);
return InkWell(
onTap: () {
_isSelected
? selectedItems.remove(item)
: selectedItems.add(item);
//This rebuilds the StatefulWidget to update the button's text
setState(() {});
//This rebuilds the dropdownMenu Widget to update the check mark
menuSetState(() {});
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
_isSelected
? const Icon(Icons.check_box_outlined)
: const Icon(Icons.check_box_outline_blank),
const SizedBox(width: 16),
Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
],
),
),
);
},
),
);
}).toList(),
//Use last selected item as the current value so if we've limited menu height, it scroll to last item.
value: selectedItems.isEmpty ? null : selectedItems.last,
onChanged: (value) {},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
itemPadding: EdgeInsets.zero,
selectedItemBuilder: (context) {
return items.map(
(item) {
return Container(
alignment: AlignmentDirectional.center,
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Text(
selectedItems.join(', '),
style: const TextStyle(
fontSize: 14,
overflow: TextOverflow.ellipsis,
),
maxLines: 1,
),
);
},
).toList();
},
),
),
),
);
}
Also, I've added it as an example to the package doc "Example 4" so you can get back to it later.

how to make switches individually marked? Flutter

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);
}
),
);
}