简体   繁体   English

从 Flutter 开始:如何让 4 个按钮填充一个 SafeArea

[英]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.我是 Dart 和 Flutter 的初学者,我的项目是在构建应用程序的同时学习。 I've learned the basics with an online class and I have basis in Java.我通过在线课程学习了基础知识,并且有 Java 基础。

Now, in my homepage, I'm trying to have 4 buttons take the whole screen.现在,在我的主页中,我试图让 4 个按钮占据整个屏幕。 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.问题是,我找不到让 RaisedButton 自动填充的方法。 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.尝试删除可变高度逻辑,只需将按钮包装在Expanded小部件中。 This is pretty much what it was built for.这几乎就是它的构建目的。

Check it out here: https://api.flutter.dev/flutter/widgets/Expanded-class.html在这里查看: 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如果 4 个按钮是唯一的小部件,则不需要使用ListView只需使用带有mainAxisAlignment: MainAxisAlignment.spaceEvenly的列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.您可以使用ColumnExpanded来完成这项工作。 If you want to make your Column scrollable, you can wrap it with SingleChildScrollView .如果你想让你的Column可滚动,你可以用SingleChildScrollView包裹它。 I used SizedBox instead of Container to make the spacing because it is way more efficient and is designed for it.我使用SizedBox而不是Container来制作间距,因为它更有效并且专为它而设计。

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.您可能会发现使用带有列表和参数 MainAxisAlignment 的容器更适合您。

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 .我通过使用SizedBox像我想要的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.首先,我恢复了屏幕的宽度,然后我创建了按钮并将它们放入适合屏幕宽度的 SizedBox 中,我将它们放入一个Column并为样式点添加了一些Container

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!现在我将添加图像和透明度以使其看起来不错!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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