Reputation: 241
I have a check box that I would like users to check that they agree to receive email promotions.
I have followed numerous resources online and can get the checkbox to render, however it does not allow for the checkbox to be selected.
This is how I am building the checkbox:
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(children: <Widget>[
// padding: const EdgeInsets.all(50.0),
Checkbox(
value: receive,
activeColor: Color(0xff33333D),
onChanged: (value) {
setState(() {
value = receive;
});
},
),
Text("I agree to receive emails",
style: TextStyle(
fontSize: 12,
))
])),
The error I am receiving is that setState isn't defined for the type SignUp
Has anyone ever received this error before? How can I rectify? Based upon my knowledge, SetState is not something that is required to be defined.
The full reproductive code sample is below:
class myApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login',
theme: ThemeData(
fontFamily: 'fonts/Avenir-Bold',
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SignUp(),
);
}
}
class SignUp extends StatelessWidget{
@override
bool receive = false;
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Image.asset(
"assets/SignUp_Photo.jpg",
height: MediaQuery.of(context).size.height * 0.3,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.all(45.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Sign Up',
style: TextStyle(
fontSize: 35,
fontFamily: 'Avenir',
fontWeight: FontWeight.w900,
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration:
InputDecoration(hintText: "First Name"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration:
InputDecoration(hintText: "Email Address"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration: InputDecoration(hintText: "Password"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(children: <Widget>[
// padding: const EdgeInsets.all(50.0),
Checkbox(
value: receive,
activeColor: Color(0xff33333D),
onChanged: (value) {
setState(() {
value = receive;
});
},
),
Text("I agree to receive emails",
style: TextStyle(
fontSize: 12,
))
])),
const SizedBox(height: 50.0),
Row(
children: [
OutlineButton(
onPressed: () {},
child: Text('Login'),
borderSide: BorderSide(
color: Color(0xff33333D),
),
),
],
),
],
)),
],
));
}
}
Upvotes: 0
Views: 74
Reputation: 55
If you want to setState
, use StatefullWidget
. Those are the widgets that have mutable states.
Convert your StatelessWidget to StatefullWidget like this:
class SignUp extends StatefulWidget{
@override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
@override
bool receive = false;
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Image.asset(
"assets/SignUp_Photo.jpg",
height: MediaQuery.of(context).size.height * 0.3,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.all(45.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Sign Up',
style: TextStyle(
fontSize: 35,
fontFamily: 'Avenir',
fontWeight: FontWeight.w900,
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration:
InputDecoration(hintText: "First Name"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration:
InputDecoration(hintText: "Email Address"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(
// padding: const EdgeInsets.all(50.0),
children: <Widget>[
Expanded(
child: TextFormField(
decoration: InputDecoration(hintText: "Password"),
),
),
],
),
),
Container(
margin: EdgeInsets.only(
top: 20, left: 0, right: 0, bottom: 0),
child: Row(children: <Widget>[
// padding: const EdgeInsets.all(50.0),
Checkbox(
value: receive,
activeColor: Color(0xff33333D),
onChanged: (value) {
setState(() {
receive = value; // value = receive; is wrong
});
},
),
Text("I agree to receive emails",
style: TextStyle(
fontSize: 12,
))
])),
const SizedBox(height: 50.0),
Row(
children: [
OutlineButton(
onPressed: () {},
child: Text('Login'),
borderSide: BorderSide(
color: Color(0xff33333D),
),
),
],
),
],
)),
],
));
}
}
Upvotes: 1
Reputation: 11249
You cannot setState on stateless widgets, that is why you got such error.
(Stateless Widget is) A widget that does not require mutable state.
You have to use a stateful widget, I advise that you read the documentation and try examples from the official site.
Upvotes: 1
Reputation: 432
If you want to use setState
, use StatefullWidget
.
And your code is wrong on setState
function.
Change
setState(() {
value = receive;
});
To
setState(() {
receive = value;
});
Upvotes: 1