Flutter:浮动操作按钮固定位置

时间:2019-05-25 21:24:44

标签: flutter dart

我有以下代码:

return Scaffold(
      appBar: AppBar(
        title: Text('Sample Code'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
          TextField(
            decoration: InputDecoration(labelText: "Text"),
          ),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );

只要键盘出现以向TextField输入文本,FloatingActionButton就会向上移动到键盘顶部,如下所示:

FloatingActionButton

我想要的是按钮停留在底部导航栏中,并且在键盘出现时不移动。我在resizeToAvoidBottomPadding: false,上添加了Scaffold,这可以防止按钮移动,但也可以使我的ListView停止移动,以便在键盘出现时保持可见。

3 个答案:

答案 0 :(得分:2)

将浮动操作按钮包装在positioned widget内对我不起作用。但是,结合在脚手架中添加属性

resizeToAvoidBottomPadding:否,

您还可以使用MediaQuery.of方法将SingleChildScrollView小部件与填充一起使用...

return Scaffold(
  resizeToAvoidBottomInset: false,
  backgroundColor: Colors.lightBlueAccent,
  floatingActionButton: FloatingActionButton(
    backgroundColor: Colors.lightBlueAccent,
    child: Icon(Icons.add),
    onPressed: () {
      showModalBottomSheet(
          context: context,
          isScrollControlled: true,
          builder: (context) => SingleChildScrollView(
              child: Container(
                  padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
                  child: AddTaskScreen())),
          backgroundColor: Colors.transparent);
    },
  ),

答案 1 :(得分:1)

也许这样做有更优雅的方法?但这会解决您眼前的问题。

有一个不错的小插件可以检测键盘可见性here。 然后,您要做的就是监听键盘的可见状态,并在键盘可见时隐藏FAB。

示例:

import 'package:flutter/material.dart';
import 'package:keyboard_visibility/keyboard_visibility.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SO Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool keyboardOpen = false;

  @override
  void initState() {
    super.initState();
    KeyboardVisibilityNotification().addNewListener(
      onChange: (bool visible) {
        setState(() => keyboardOpen = visible);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample Code'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          TextField(decoration: InputDecoration(labelText: "Text")),
          TextField(decoration: InputDecoration(labelText: "Text")),
          TextField(decoration: InputDecoration(labelText: "Text")),
        ],
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(height: 50.0),
      ),
      floatingActionButton: keyboardOpen
          ? SizedBox()
          : FloatingActionButton(
              onPressed: () {},
              child: Icon(Icons.add),
            ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

答案 2 :(得分:0)

只需使用脚手架内部的属性 resizeToAvoidBottomInset:假

它将立即解决问题。