RhysD
RhysD

Reputation: 1657

Flutter Animated Container

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

Answers (3)

Curt Eckhart
Curt Eckhart

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

NiklasPor
NiklasPor

Reputation: 9815

The code snippet you've posted is already correct. Make sure that:

  • loginWidth is initialized
  • the new loginWidth value is actually different from the default value

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:

Demo

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

Benjith Kizhisseri
Benjith Kizhisseri

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

Related Questions