简体   繁体   中英

Beginning in Flutter: How do I make 4 buttons fill a SafeArea

I've very much a beginner in Dart and Flutter, and my project is to learn while building an app. I've learned the basics with an online class and I have basis in Java.

Now, in my homepage, I'm trying to have 4 buttons take the whole screen. My current layout is to have them all take an equal amount of space and be stacked vertically. Problem is, I can't find a way to make the RaisedButton fill automatically. I've tried retrieving the height of the screen and dividing that between the buttons but it's not working. Here's how I do it : First, the homescreen layout:

class Homescreen extends StatelessWidget {
  Widget build(context) {
    double height = MediaQuery.of(context).size.height - 60;
    return Scaffold(
      body: SafeArea(
        child: ListView(
          children: [
            PlanningButton(height),
            Container(margin: EdgeInsets.only(top: 20.0)),
            BookingButton(height),
            Container(margin: EdgeInsets.only(top: 20.0)),
            ModifyButton(height),
            Container(margin: EdgeInsets.only(top: 20.0)),
            CancelButton(height),
          ],
        ),
      ),
    );
  }

As you can see, I pass the height argument to my buttons all built around this model:

  Widget PlanningButton(double pixel_y) {
    return RaisedButton(
      padding: EdgeInsets.all(pixel_y / 8.0),
      onPressed: () {}, //goes to the planning screen
      color: Colors.blue[200],
      child: Text("Planning"),
    );
  }

Yet, it's never quite right. I don't think it's taking into account the notification bar or the navigation bar. I suspect there is a workaround that involves wrapping the buttons into a container or using a different kind of widget that have button-like properties but I can't find what suits my needs.

Thanks for any help !

edit: I'm basically trying to do this

Try removing the variable height logic, and simply wrap your buttons in Expanded widgets. This is pretty much what it was built for.

Check it out here: https://api.flutter.dev/flutter/widgets/Expanded-class.html

If 4 buttons are the only widgets, you dont need to use ListView just use a Column with mainAxisAlignment: MainAxisAlignment.spaceEvenly

class Sample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Expanded(
              child: Container(
                color: Colors.red,
                child: Center(
                  child: RaisedButton(
                    onPressed: () {},
                    child: Text("button"),
                  ),
                ),
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.blue,
                child: Center(
                  child: RaisedButton(
                    onPressed: () {},
                    child: Text("button"),
                  ),
                ),
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.green,
                child: Center(
                  child: RaisedButton(
                    onPressed: () {},
                    child: Text("button"),
                  ),
                ),
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.yellow,
                child: Center(
                  child: RaisedButton(
                    onPressed: () {},
                    child: Text("button"),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在此处输入图片说明

You could use a Column and Expanded to do the job. If you want to make your Column scrollable, you can wrap it with SingleChildScrollView . I used SizedBox instead of Container to make the spacing because it is way more efficient and is designed for it.

class Homescreen extends StatelessWidget {
  Widget build(context) {
    double height = MediaQuery.of(context).size.height - 60;
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              child: PlanningButton(height)
            ),
            SizedBox(height:20),
            Expanded(
              child: BookingButton(height),
            ),
            SizedBox(height:20),
            Expanded(
              child: ModifyButton(height),
            ),
            SizedBox(height:20),
            Expanded(
              child: CancelButton(height),
            ),
          ],
        ),
      ),
    );
  }

Before you read this, it's not the best way to do things but it's one I'm using at least for prototyping. You may find using a container with a list and the argument MainAxisAlignment to work better for you.

A lot of comments here might give a solution that works for you but here's mine. I got it to work like I wanted by using SizedBox .

First, I recovered the width of the screen, then I created the buttons and put them into SizedBox fitting the screen's width, I put them in a Column and I added a few Container for the style points.

Result: 在此处输入图片说明

Code :

class Homescreen extends StatelessWidget {
  Widget build(context) {
    double width = MediaQuery.of(context).size.width; //getting screen width
    return Scaffold(
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Container(margin: EdgeInsets.only(bottom: 20.0)),
            PlanningButton(width),
            Container(margin: EdgeInsets.only(bottom: 20.0)),
            BookingButton(width),
            Container(margin: EdgeInsets.only(bottom: 20.0)),
            ModifyButton(width),
            Container(margin: EdgeInsets.only(bottom: 20.0)),
            CancelButton(width),
            Container(margin: EdgeInsets.only(bottom: 20.0)),
          ],
        ),
      ),
    );
  }

  Widget PlanningButton(double width) {
    return Expanded(
      child: SizedBox(
        width: width - 20,
        child: RaisedButton(
          onPressed: () {},
          color: Colors.blue,
          child: Text(
            "planning",
            textScaleFactor: 4.0,
          ),
        ),
        //fit: BoxFit.cover,
      ),
    );
  }

The user can tap anywhere on the colored buttons and it will register. Now I'll add images and transparency to make it look good!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM