Aaron Zolla
Aaron Zolla

Reputation: 602

Widget not going to bottom of screen in Flutter?

So I'm trying to get the REGISTER button to align on the bottom center of the screen. I'm relatively new to Flutter and am wondering if there is a way to do this easily, or do I need to rewrite a lot of code? Here's what I have so far. As you can see, I put it in an Align(), but it only goes to the bottom center of the filled area. I think what I have to do is make the outside Container() the height of the entire screen, but I also don't know how to do this. If you have a way to do this, please let me know. Thanks.

import 'package:flutter/material.dart';

class LoginSignupScreen extends StatefulWidget {
  @override
  _LoginSignupScreenState createState() => _LoginSignupScreenState();
}

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  // TRUE: register page, FALSE: login page
  bool _register = true;

  void _changeScreen() {
    setState(() {
      // sets it to the opposite of the current screen
      _register = !_register;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
//      height:,
      child: Column(
//      mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ButtonBar(
                  children: <Widget>[
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('REGISTER'),
                    ),
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('LOGIN'),
                    ),
                  ],
                ),
              ],
            ),
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'E-MAIL'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'USERNAME'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'PASSWORD'),
                )
              ],
            ),
          ),
          Align(
            alignment: FractionalOffset.bottomCenter,
            child: MaterialButton(
              onPressed: () => {},
              child: Text(_register ? 'REGISTER' : 'LOGIN'),
            ),
          ),
        ],
      ),
    );
  }
}

Upvotes: 45

Views: 111040

Answers (9)

AzeTech
AzeTech

Reputation: 697

Use SingleChildScrollView with SixedBox height to screen size. Here in the below code, Text will appear in top and content that need to display at bottom is separated by Spacer() and finally button is placed

  @override   Widget build(BuildContext context) {
        return Scaffold(
          body: SingleChildScrollView(
           padding: EdgeInsets.symmetric(horizontal: 21,),
           child: SizedBox(
           height: MediaQuery.of(context).size.height,
           child: Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: [
            Text( "Address",
            style: TextStyle( color: YourColor,
           fontSize: YourSize,
           fontWeight: YourFontWeight
            ),
            ),
            spacer(), //after spacer contentwill diplay at the bottom ofscreen
            /// Below button will go to bottom
             ElevatedButton(
              onPressed: (){},
              child: Text('Click'),
            ),   
     ]  
   ))   
 );  
}

Upvotes: 1

Sabahat Hussain Qureshi
Sabahat Hussain Qureshi

Reputation: 1354

You can use Spacer() widget before Register Button

class TestApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<TestApp> {
  bool _register = true;

  void _changeScreen() {
    setState(() {
      // sets it to the opposite of the current screen
      _register = !_register;
    });
  }

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(
        title: Text("Hospital Management"),
      ),
      body: Container(
//      height:,
      child: Column(
//      mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ButtonBar(
                  children: <Widget>[
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('REGISTER'),
                    ),
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('LOGIN'),
                    ),
                  ],
                ),
              ],
            ),
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'E-MAIL'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'USERNAME'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'PASSWORD'),
                )
              ],
            ),
          ),
          Spacer(),
          Align(
            alignment: FractionalOffset.bottomCenter,
            child: MaterialButton(
              onPressed: () => {},
              child: Text(_register ? 'REGISTER' : 'LOGIN'),
            ),
          ),
        ],
      ),
    ),
    );
  }
}

Upvotes: 2

Kavya Shravan
Kavya Shravan

Reputation: 363

Try with bottomNavigationBar

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(),
      ),
      bottomNavigationBar: YourButtonWidget(),
    );
  }

Upvotes: 2

Jitesh Mohite
Jitesh Mohite

Reputation: 34170

Wrap all widgets with Expanded Widget excluding the last one, Expanded widget basically takes max available space. Look at the below example you will get to know

Code:

Column(
        children: [
          Expanded(
            child: Container(
              color: Colors.grey,
            ),
          ),
          /// Below container will go to bottom
          ElevatedButton(
            onPressed: (){},
            child: Text('Click'),

          )
        ],
      ),

Output:

enter image description here

Upvotes: 7

Animesh Banerjee
Animesh Banerjee

Reputation: 311

There is another way to solve this:

children : [
           ///1
           Button(),

           Expanded(child:Container()),

           ///2
           Button(),
           ]

Logic: by expanded container will absorb the middle space in between the two buttons by which the second button will placed at bottom of the screen.

Upvotes: 19

Andrew
Andrew

Reputation: 735

There is an easier way:

return Scaffold(     
  bottomNavigationBar: BottomAppBar(
    color: Colors.transparent,
    child: Text('bottom screen widget'),
    elevation: 0,
  ),
  body: Text('body')
  );

Upvotes: 48

ko2ic
ko2ic

Reputation: 2092

You will solve using Expanded widget.

        Expanded(
          child: Align(
            alignment: FractionalOffset.bottomCenter,
            child: MaterialButton(
              onPressed: () => {},
              child: Text(_register ? 'REGISTER' : 'LOGIN'),
            ),
          ),
        ),

enter image description here

Upvotes: 107

bytesizedwizard
bytesizedwizard

Reputation: 6033

You can set the Container height to cover the entire screen as you mentioned and then just wrap your Align widget inside an Expanded widget, which will fill the available space.

Try this code:

Widget build(BuildContext context) {
    return Container(
      height: MediaQuery.of(context).size.height,
      child: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ButtonBar(
                  children: <Widget>[
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('REGISTER'),
                    ),
                    MaterialButton(
                      onPressed: _changeScreen,
                      child: Text('LOGIN'),
                    ),
                  ],
                ),
              ],
            ),
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              children: <Widget>[
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'E-MAIL'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'USERNAME'),
                ),
                TextField(
                  decoration: InputDecoration(
                      border: InputBorder.none, hintText: 'PASSWORD'),
                )
              ],
            ),
          ),
          Expanded(
            child: Align(
              alignment: Alignment.bottomCenter,
              child: MaterialButton(
                onPressed: () => {},
                child: Text(_register ? 'REGISTER' : 'LOGIN'),
              ),
            ),
          )
        ],
      ),
    );
  }

Upvotes: 8

UnderdoX
UnderdoX

Reputation: 255

Try This :

import 'package:flutter/material.dart';

class LoginSignupScreen extends StatefulWidget {
  @override
  _LoginSignupScreenState createState() => _LoginSignupScreenState();
}

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  // TRUE: register page, FALSE: login page
  bool _register = true;

  void _changeScreen() {
    setState(() {
      // sets it to the opposite of the current screen
      _register = !_register;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
//      height:,
        child: Column(
//      mainAxisAlignment: MainAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(20),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  ButtonBar(
                    children: <Widget>[
                      MaterialButton(
                        onPressed: _changeScreen,
                        child: Text('REGISTER'),
                      ),
                      MaterialButton(
                        onPressed: _changeScreen,
                        child: Text('LOGIN'),
                      ),
                    ],
                  ),
                ],
              ),
            ),
            Padding(
              padding: EdgeInsets.all(20),
              child: Column(
                children: <Widget>[
                  TextField(
                    decoration: InputDecoration(
                        border: InputBorder.none, hintText: 'E-MAIL'),
                  ),
                  TextField(
                    decoration: InputDecoration(
                        border: InputBorder.none, hintText: 'USERNAME'),
                  ),
                  TextField(
                    decoration: InputDecoration(
                        border: InputBorder.none, hintText: 'PASSWORD'),
                  )
                ],
              ),
            ),
            Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                MaterialButton(
                  onPressed: () => {},
                  child: Text(_register ? 'REGISTER' : 'LOGIN'),
                ),
              ],
            )
          ],
        ),
      ),
    );
  }
}

Upvotes: 5

Related Questions