Reputation: 1657
I have a RaisedButton
widget and an AnimatedContainer
widget in a screen, and the idea is that upon pressing the RaisedButton
the width of the AnimatedContainer
would then decrease in a given duration. The documentation of the AnimatedContainer
states that all I would need to do is declare the width of the widget as a variable, and then setState(() {})
after changing the value and it will automatically change to that value during the duration. I have tried to implement this and upon pressing the RaisedButton
the variables value definitely changes (based on printing the value of it after pressing it), however the widget's width does not change with it. Am I missing something obvious?
My Widgets are within a container in a PageView
and my code for the RaisedButton
and AnimatedContainer
is as follows:
RaisedButton (
onPressed: () {
setState(() {
loginWidth = 70.0;
});
},
),
AnimatedContainer (
duration: new Duration (seconds: 2),
width: loginWidth,
height: 40,
color: Colors.red,
)
Here is my widget tree:
pages.add(
Container(
color: chSecondary,
child: Stack(
children: <Widget>[
Container (
child: Align (
child: Image(image: AssetImage("graphics/signin.png")),
alignment: Alignment.bottomCenter,
),
),
Form(
key: _formKey,
child: new Container(
padding: EdgeInsetsDirectional.only(top: 100, start: 15, end: 15, bottom: 15),
child: new Column(
children: <Widget>[
Container (
child: Image(image: AssetImage("graphics/login.png"), height: 200, width: 200,),
margin: EdgeInsetsDirectional.only(bottom: 20),
),
Container (
padding: EdgeInsets.all(25.0),
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white,
),
child: Column (
children: <Widget>[
Align(
child: new Text("Email:", style: TextStyle(fontSize: tonSubTitle, color: Colors.black)),
alignment: Alignment.centerLeft,
),
new Container(
child: new TextFormField(
keyboardType: TextInputType.emailAddress,
controller: _email,
style: TextStyle(fontSize: tonText, color: Colors.black),
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: new BorderRadius.circular(tonRadius)),
contentPadding: EdgeInsetsDirectional.only(top: 15, start: 7.5),
focusedBorder: OutlineInputBorder(borderSide: new BorderSide(color: Colors.grey)),
hintText: "Email Address",
hintStyle: TextStyle(color: Colors.black),
),
validator: (value) {
if (value.isEmpty) {
return "Please enter an email";
}
if (!value.contains("@tonbridge-school.org")) {
return "Please enter a valid email address";
}
},
),
padding: const EdgeInsets.only(top: 10, bottom: 10)
),
Align (
child: new Text("Password:", style: TextStyle(fontSize: tonSubTitle, color: Colors.black)),
alignment: Alignment.centerLeft,
),
new Container(
child: new TextFormField(
obscureText: true,
controller: _password,
style: TextStyle(color: Colors.black, fontSize: tonText),
decoration: InputDecoration(
contentPadding: EdgeInsetsDirectional.only(top: 15, start: 7.5),
border: OutlineInputBorder(borderRadius: new BorderRadius.circular(tonRadius)),
focusedBorder: OutlineInputBorder(borderSide: new BorderSide(color: Colors.grey)),
hintText: "Password",
hintStyle: TextStyle(color: Colors.black),
),
validator: (value) {
if (value.isEmpty) {
return "Please enter a password";
}
},
),
padding: const EdgeInsets.only(top: 10, bottom: 10)
),
RaisedButton (
onPressed: () {
setState(() {
loginWidth = 70.0;
});
},
),
AnimatedContainer (
duration: new Duration (seconds: 2),
width: loginWidth,
height: 40,
color: Colors.red,
)
],
),
)
],
),
)
),
],
),
),
);
Upvotes: 6
Views: 34854
Reputation: 495
Where do you have loginWidth declared? It needs to outside the scope of the builder function or its value will get reinitialized on every build.
Can you update your example to show where you declare?
Correct:
class _WidgetState extends State<Widget> {
double loginWidth = 0;
@override
Widget build(BuildContext context) {
// return the new widget tree
}
}
Incorrect:
class _WidgetState extends State<Widget> {
@override
Widget build(BuildContext context) {
double loginWidth = 0;
//return the new widget tree
}
}
Upvotes: 0
Reputation: 9815
The code snippet you've posted is already correct. Make sure that:
I've copied it and built a minimal example so you can double check the rest of your code. This example also include a surrounding PageView:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyBody(),
),
);
}
}
class MyBody extends StatefulWidget {
@override
_MyBodyState createState() => _MyBodyState();
}
class _MyBodyState extends State<MyBody> {
double loginWidth = 40.0;
@override
Widget build(BuildContext context) {
return Center(
child: PageView(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
RaisedButton (
child: Text('Animate!'),
onPressed: () {
setState(() {
loginWidth = 250.0;
});
},
),
AnimatedContainer (
duration: Duration (seconds: 1),
width: loginWidth,
height: 40,
color: Colors.red,
),
],
)
],
),
);
}
}
Upvotes: 4
Reputation: 2678
do you initialised loginWidth ?
var loginWidth =0.0;
Curve _curve = Curves.fastOutSlowIn;
_doanimation(){
setState(() {
loginWidth ==0.0? loginWidth =100: loginWidth =0.0;
});
}
change function with your case
Column(
children: <Widget>[
Text("welcome"),
RaisedButton(
onPressed: (){
_doanimation();
},
),
AnimatedContainer(
curve: _curve,
duration: Duration(seconds: 1),
width: loginWidth,
height:100
)
],
),
Upvotes: 0