Flutter - FloatingActionButton 在中心

Flutter - FloatingActionButton in the center

是否可以将 FloatingActionButton 放在中间而不是右边?

import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';

class ContaPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    body: new Column(
      children: <Widget>[
        new Number(),
        new Keyboard(),
      ],
    ),
    floatingActionButton: new FloatingActionButton(
      elevation: 0.0,
      child: new Icon(Icons.check),
      backgroundColor: new Color(0xFFE57373),
      onPressed: (){}
    )
  );
}

我修改了代码,现在按钮在底部居中,但不知道会不会一直在底部,不管屏幕大小。

import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';

class ContaPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    body: new Column(
      children: <Widget>[
        new Number(),
        new Keyboard(),
        new Stack(
          alignment: new FractionalOffset(0.5, 1.0),
          children: <Widget>[
            new FloatingActionButton(
              elevation: 0.0,
              child: new Icon(Icons.check),
              backgroundColor: new Color(0xFFE57373),
              onPressed: (){}
            )
          ],
        )
      ],
    ), 
  );
}

尝试将其包装在 Center 小部件中或在 Column.

上使用 CrossAxisAlignment.centercrossAxisAlignment

您应该选择 Column 的一部分包裹在 Flexible 中,该 Flexible 会折叠以避免溢出,或者用 ListView 替换部分或全部,以便用户可以滚动查看隐藏的部分。

通过更改逻辑以使用 crossAxisAlignment,将 mainAxisAlignment 和 Flexible FloatingActionButton 居中放置在屏幕底部

import 'package:flutter/material.dart';
import 'number.dart';
import 'keyboard.dart';

class ContaPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    body: new Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.spaceBetween,       
      children: <Widget>[
        new Number(),
        new Keyboard(),
        new Flexible(
          child: new Container(
            padding: new EdgeInsets.only(bottom: 16.0),
            child: new FloatingActionButton(
              elevation: 0.0,
              child: new Icon(Icons.check),
              backgroundColor: new Color(0xFFE57373),
              onPressed: (){}
            )
          )         
        )
      ],
    ), 
  );
}

我不知道这个问题是不是在第一次回答后添加的,但是 floatingActionButtonLocation 属性 在 Scaffold class.

在你原来的问题中它会像这样工作:

class ContaPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    // ...

    floatingActionButton: new FloatingActionButton(
      // ...FloatingActionButton properties...
    ),

    // Here's the new attribute:

    floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
  );
}

另请参阅文档:

使用新的 flutter API 你可以很容易地做到这一点,只需将脚手架中的 floatingActionButtonLocation 属性 更改为

FloatingActionButtonLocation.centerFloat

Example :

return new Scaffold(
  floatingActionButton: new FloatingActionButton(
    child: const Icon(Icons.add),
  ),
  floatingActionButtonLocation:    
      FloatingActionButtonLocation.centerFloat,
  bottomNavigationBar: new BottomAppBar(
    color: Colors.white,
    child: new Row(...),
  ),
);

您可以使用容器和对齐小部件,如下所示:

@override
Widget build(BuildContext context) {
    return new Scaffold(
      body: Center(

      ),
      floatingActionButton: Container(
        padding: EdgeInsets.only(bottom: 100.0),
        child: Align(
          alignment: Alignment.bottomCenter,
          child: FloatingActionButton.extended(
            onPressed: _getPhoneAuthResult,
            icon: Icon(Icons.phone_android),
            label: Text("Authenticate using Phone"),
          ),
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }

浮动操作按钮小部件结束后,您可以使用floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,

例如

   import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

void main() => runApp(MyApp());

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

class _MyAppState extends State<MyApp> {
  File _image;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      title: "Camera App",
      home: Scaffold(
        appBar: AppBar(
          title: Text("Camera App"),
        ),
        body: Center(
          child: Center(
            child: _image == null
                ? Text('No image selected.')
                : Image.file(_image,
                alignment: Alignment.topLeft,
                ),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          elevation: 50,
          hoverColor: Colors.red,
          autofocus: true,
          onPressed: () {
            imagepicker();
          },
          child: Icon(Icons.camera_alt),
          tooltip: 'Pick Image',
        ),
         floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      ),
    );
  }

  Future imagepicker() async {
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      _image = image;
    });
  }
}
Align(
                      alignment: Alignment.center,
                      child: Container(
                        child: FloatingActionButton(
                          hoverColor: Colors.black,
                          elevation: 10,
                          onPressed: () {},
                          backgroundColor: Colors.pink,
                          child: Icon(Icons.add,),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.all(Radius.circular(20.0))),
                        ),
                      ),
                    ),

这里我使用 "Align" 小部件使 FloatingActionButton 居中。 You can see it here.

使用 属性 floatingActionButtonLocation of scaffold class.

floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,

完整示例:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: HomePage()
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(child: Center(child: Text('Hello World')),),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.camera, color: Colors.white, size: 29,),
        backgroundColor: Colors.black,
        tooltip: 'Capture Picture',
        elevation: 5,
        splashColor: Colors.grey,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,

在脚手架中将此 属性 与 floatingActionButtonLocation 属性 结合使用。

FloatingActionButton Flutter - More Details

上面的例子很好,但是如果你想完全控制浮动操作按钮的确切位置,你应该用 Align 小部件包裹你的 FloatingActionButton 小部件并使用 Alignment(x axis, y axis) 来设置确切位置。

Align(
  alignment: Alignment(0.0, 0.8), 
//control the location by changing the numbers here to anything between 1 and -1
  child: FloatingActionButton()
)

要获得更多对齐自由度和超过 2 个 FAB,请使用 Stack

Stack(
      children: <Widget>[
        Center(
          child: Center(
            child: _image == null
                ? Text('No image selected.')
                : Image.file(_image,
                alignment: Alignment.topLeft,
                ),
          ),
        ),
        Align(
          alignment: Alignment.centerLeft,
          child: new FloatingActionButton(
              child: const Icon(Icons.skip_previous),
              onPressed: () {
              }),
        ),
        Align(
          alignment: Alignment.centerRight,
          child: new FloatingActionButton(
              child: const Icon(Icons.skip_next),
              onPressed: () {
              }),
        ),
      ],
    )

Scaffold.floatingActionButton just asks for a Widget, you can wrap your FloatingActionButton with the standard classes for more control if the Scaffold.floatingActionButtonLocation property isn't enough (which already gives you many standard placements 以来,它也可以很好地与您的 appBarbottomNavigationBar) 一起播放。

Container 是一个经典组件,但考虑到它结合了各种小部件,有点矫枉过正。

正如其他人提到的,Align is handy when you want to position relative to the Align widget itself (which if unconstrained fills to its parent). It can take a variety of preset Alignment常量,或者使用Alignment构造函数来指定你自己的相对位置,例如Alignment(0.0, 0.0)代表矩形的中心,(1,1)代表右下角,(-1,-1)代表左上角。但是,您的 FAB 的父级受脚手架的 floatingActionButtonLocation: 的影响,因此一种帮助考虑它的方法是将其设置为 FloatingActionButtonLocation.centerDocked,当与 Align 一起使用时,您可以认为关于相对于屏幕中心的定位。

但也许您喜欢 floatingActionButtonLocation 提供的基本定位,但只想将 FAB 移动已知数量的逻辑像素,例如以补偿屏幕上的其他小部件。在那种情况下,用适当的 EdgeInsets 包装在 Padding 中应该可以正常工作。