Reido
Reido

Reputation: 13

flutter button as variable is different than non-variable

I declared a loginButton variable and used it later in the build. For some reason Flutter hot load doesn't update it on the device if I change something in the variable. Only after restarting debbuging. Using VS Code.

I inserted the same button configuration straight into the build. Changing this one changes on the device after a hot load. BUT it's looking different. The height is about double.

Why doesn't the variable one refresh after a hot load and why is it looking different?

import 'package:flutter/material.dart';

class FirstScreen extends StatelessWidget {
  final loginButton = Padding(
    padding: EdgeInsets.symmetric(vertical: 16.0),
    child: Material(
      borderRadius: BorderRadius.all(Radius.zero),
      shadowColor: Colors.grey[200],
      elevation: 5.0,
      child: MaterialButton(
        minWidth: 200.0,
        height: 60.0,
        onPressed: null,
        color: Colors.grey,
        child: Text(
          'LOG IN',
          style: TextStyle(
            color: Colors.white,
            fontSize: 24.0,
          ),
        ),
      ),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Split',
      home: Scaffold(
        body: Center(
          child: ListView(
            padding: EdgeInsets.only(left: 24.0, right: 24.0, top: 200.0),
            children: <Widget>[
              loginButton,
              Padding(
                padding: EdgeInsets.symmetric(vertical: 16.0),
                child: Material(
                  borderRadius: BorderRadius.all(Radius.zero),
                  shadowColor: Colors.grey[200],
                  elevation: 5.0,
                  child: MaterialButton(
                    minWidth: 200.0,
                    height: 60.0,
                    onPressed: null,
                    color: Colors.grey,
                    child: Text(
                      'LOG IN',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 24.0,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Upvotes: 1

Views: 527

Answers (1)

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277077

That is because hot reload is a stateful reload. Which implies that currently set variables are not reset on hot reload. As you'd lose the state of your app.

Instead of storing these into a field of your class, extract them into a custom widget such as the following :

class LoginButton extends StatelessWidget {
  const LoginButton({Key key}): super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 16.0),
      child: Material(
        borderRadius: BorderRadius.all(Radius.zero),
        shadowColor: Colors.grey[200],
        elevation: 5.0,
        child: MaterialButton(
          minWidth: 200.0,
          height: 60.0,
          onPressed: null,
          color: Colors.grey,
          child: Text(
            'LOG IN',
            style: TextStyle(
              color: Colors.white,
              fontSize: 24.0,
            ),
          ),
        ),
      ),
    );
  }
}

And then you can freely reuse it inside your build method :

@override
Widget build(BuildContext context) {
  return const LoginButton();
}

You could also store it inside a custom field. Hot reload would still work here, as you're editing the content of LoginButton not the value of a class field.

But since in your case LoginButton can be built using dart const constructors, it's even better to use these over a class field.

Upvotes: 2

Related Questions