Reputation: 83
i tried to change new state with Switch widget but it can't be used, in case i create dynamic function and will to used in widget tree's, in function i send callback function at parameter for Switch widget, but in actual it is cannot be used.
code base
import 'package:flutter/material.dart';
import 'package:navigate_app/widgets/main_drawer.dart';
class FilterScreen extends StatefulWidget {
static const routeNamed = '/filter';
@override
State<FilterScreen> createState() => _FilterScreenState();
}
class _FilterScreenState extends State<FilterScreen> {
bool _glutenFree = false;
bool _vegetarian = false;
bool _vegan = false;
bool _lactoseFree = false;
Widget _buildSwitchFilter(String title, String description, bool currentValue,
Function updateValue) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: (val) => updateValue);
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: MainDrawer(),
appBar: AppBar(),
body: Column(
children: [
Expanded(
child: ListView(
children: [
_buildSwitchFilter('Gluten-free',
'Only include gluten-free meals', _glutenFree, (newVal) {
setState(() {
_glutenFree == newVal;
});
}),
_buildSwitchFilter(
'Lactose-free',
'Only include lactose-free meals',
_glutenFree,
(newVal) => _lactoseFree == newVal),
_buildSwitchFilter(
'Vegan-free',
'Only include vegan-free meals',
_glutenFree,
(newVal) => _vegan == newVal),
_buildSwitchFilter(
'Vegetarian-free',
'Only include vegetarian-free meals',
_glutenFree,
(newVal) => _vegetarian == newVal),
],
))
],
));
}
}
Upvotes: 3
Views: 1943
Reputation: 1
In addition to these corrections, you need to use the correct boolean variables (_vegetarian, _vegan, _lactoseFree) for each of your _buildSwitchFilter widgets. Also, it should be "vegan", not "vegan-free".
Upvotes: 0
Reputation: 363
Here in code are 4 problems:
You need to use "=" operator instead of "==" (_glutenFree = newVal instead of _glutenFree == newVal)
You need to pass to the _buildSwitchFilter() - "Function(bool) updateValue" as an argument, and use "onChanged: updateValue":
Widget _buildSwitchFilter(String title, String description, bool currentValue,
Function(bool) updateValue) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: updateValue);
}
You passing everywhere _glutenFree as third argument in _buildSwitchFilter(), but you need to pass:
_glutenFree;
_lactoseFree;
_vegan;
_vegetarian;
Here is the solution:
import 'package:flutter/material.dart';
import 'package:navigate_app/widgets/main_drawer.dart';
class FilterScreen extends StatefulWidget {
static const routeNamed = '/filter';
@override
State<FilterScreen> createState() => _FilterScreenState();
}
class _FilterScreenState extends State<FilterScreen> {
bool _glutenFree = false;
bool _vegetarian = false;
bool _vegan = false;
bool _lactoseFree = false;
Widget _buildSwitchFilter(String title, String description, bool currentValue,
Function(bool) updateValue) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: updateValue);
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: MainDrawer(),
appBar: AppBar(),
body: Column(
children: [
Expanded(
child: ListView(
children: [
_buildSwitchFilter('Gluten-free',
'Only include gluten-free meals', _glutenFree, (newVal) {
setState(() {
_glutenFree = newVal;
});
}),
_buildSwitchFilter(
'Lactose-free',
'Only include lactose-free meals',
_lactoseFree,
(newVal) {
setState(() {
_lactoseFree = newVal;
});
}),
_buildSwitchFilter(
'Vegan-free',
'Only include vegan-free meals',
_vegan,
(newVal) {
setState(() {
_vegan = newVal;
});
}),
_buildSwitchFilter(
'Vegetarian-free',
'Only include vegetarian-free meals',
_vegetarian,
(newVal) {
setState(() {
_vegetarian = newVal;
});
}),
],
))
],
));
}
}
Upvotes: 0
Reputation: 774
import 'package:flutter/material.dart';
import 'package:navigate_app/widgets/main_drawer.dart';
class FilterScreen extends StatefulWidget {
static const routeNamed = '/filter';
@override
State<FilterScreen> createState() => _FilterScreenState();
}
class _FilterScreenState extends State<FilterScreen> {
bool _glutenFree = false;
bool _vegetarian = false;
bool _vegan = false;
bool _lactoseFree = false;
Widget _buildSwitchFilter(String title, String description, bool currentValue,
Function(bool) updateValue) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: (val) => updateValue);
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: MainDrawer(),
appBar: AppBar(),
body: Column(
children: [
Expanded(
child: ListView(
children: [
_buildSwitchFilter('Gluten-free',
'Only include gluten-free meals', _glutenFree, (newVal) {
setState(() {
_glutenFree = newVal;
});
}),
_buildSwitchFilter(
'Lactose-free',
'Only include lactose-free meals',
_lactoseFree,
(newVal) {
setState(() {
_lactoseFree = newVal;
});
} ),
_buildSwitchFilter(
'Vegan-free',
'Only include vegan-free meals',
_vegan,
(newVal) {
setState(() {
_vegan = newVal;
});
} ),
_buildSwitchFilter(
'Vegetarian-free',
'Only include vegetarian-free meals',
_vegetarian,
(newVal) {
setState(() {
_vegetarian = newVal;
});
} ),
],
))
],
));
}
}
Upvotes: 1
Reputation: 5973
== is a method operator
basically is an equality operator. The default behavior for all Objects is to return true if and only if this and others are the same object. Override this method to specify a different equality relation on a class.
_buildSwitchFilter('Gluten-free',
'Only include gluten-free meals', _glutenFree, (newVal) {
setState(() {
_glutenFree == newVal;
});
}),
basically this line work as conditional operator _glutenFree == newVal;
So, if you want to assign any value to any variable like as you want to assign `_glutenFree = false/true
So, on that condition, you should use the assignment operator "="
like right way is,
_glutenFree = newVal;
Upvotes: 2
Reputation: 610
There are several reasons why this isn't working:
Widget _buildSwitchFilter(
String title,
String description,
bool currentValue,
Function updateValue,
) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: (val) => updateValue);
}
Should instead be:
Widget _buildSwitchFilter(
String title,
String description,
bool currentValue,
Function(bool value) updateValue, // <- note the return value
) {
return SwitchListTile(
title: Text(title),
subtitle: Text(description),
value: currentValue,
onChanged: (val) => updateValue(val)); // <- passing the `val` to your callback
}
Copypasta'd ListView
children. Each _buildSwitchFilter()
should have the related state value as to what they're for, but each uses _glutenFree
as their state value.
3 out of 4 switches aren't calling setState()
when their callback is triggered.
You're not updating local state values, you're comparing equality.
setState(() {
_glutenFree == newVal;
});
Should be:
setState(() {
_glutenFree = newVal;
});
Upvotes: 3
Reputation: 1294
This is incorrect
_glutenFree == newVal;
==
is an equality operator
https://api.dart.dev/be/137051/dart-core/Object/operator_equals.html
What u need is to assign the value using =
Correct:
_glutenFree = newVal;
Do the same for the others
Upvotes: 7