【问题标题】:Keyboard keeps covering textfields in Flutter键盘不断覆盖 Flutter 中的文本字段
【发布时间】:2020-10-13 13:30:10
【问题描述】:

我的问题是:当我使用 TextFormFields 滚动页面并单击其中一个时,键盘会越过它们。 我只有一个解决方案:增加底部填充以使该字段不再被覆盖,但这会使布局变得丑陋,因为现在我有很大一部分屏幕没有任何用处。

对此广受好评的回应是:“使用 MediaQuery.of(context).viewInsets.bottom”

但这不起作用。

在脚手架中将 resizeToAvoidBottomPadding 设置为 true 不起作用。

用 SingleChildScrollView 包装我的小部件也不起作用。

这发生在我使用它的两种姿势中:在脚手架下和在 showModalBottomSheet() 下。 有没有其他解决办法?

编辑:如果代码真的有什么不同,那就是:

return Scaffold(
      drawer: CustomDrawer(),
      appBar: CustomAppBar(
        title: widget.school != null ? 'a' : 'b',
        hasBackButton: true,
      ),
      body: BackgroundCard(
        padding: const EdgeInsets.all(24.0),
        child: Padding(
          padding:
              EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Form(
                key: _formKey,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    CustomTextFormField(
                      title: 'CNPJ:',
                      controller: _controllers[0],
                    ),
           ...

这是背景卡片:

class BackgroundCard extends StatefulWidget {
  BackgroundCard({
    @required this.child,
    this.padding,
    this.bottomPadding = 0,
    this.filterAction,
    this.addAction,
    this.addTitle,
    this.tileCount = 0,
  });
  final Widget child;
  final EdgeInsets padding;
  final double bottomPadding;
  final String addTitle;
  final VoidCallback addAction;
  final VoidCallback filterAction;
  final int tileCount;

  @override
  _BackgroundCardState createState() => _BackgroundCardState();
}

class _BackgroundCardState extends State<BackgroundCard> {
  @override
  Widget build(BuildContext context) {
    bool hasTopButton =
        widget.addAction != null || widget.filterAction != null ? true : false;

    return SingleChildScrollView(
      child: Padding(
        padding: EdgeInsets.fromLTRB(
          16.0,
          24.0 - (hasTopButton ? 12 : 0),
          16.0,
          48.0,
        ),
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                if (widget.filterAction != null)
                  OutlineButton(
                    borderSide: BorderSide(color: kYellow, width: 1.6),
                    onPressed: () => widget.filterAction(),
                    child: Row(
                      children: <Widget>[
                        Icon(Icons.search, color: kYellow),
                        SizedBox(width: 12.0),
                        Text(
                          'Filter',
                          style: Theme.of(context)
                              .textTheme
                              .headline5
                              .apply(color: kYellow),
                        ),
                      ],
                    ),
                  ),
                Spacer(),
                if (widget.addAction != null)
                  RaisedButton(
                    onPressed: () => widget.addAction(),
                    color: kYellow,
                    child: Text(
                      widget.addTitle ?? '',
                      style: Theme.of(context)
                          .textTheme
                          .headline5
                          .apply(color: kWhite),
                    ),
                  ),
              ],
            ),
            hasTopButton ? SizedBox(height: 12.0) : Container(),
            Container(
              padding: widget.padding ?? const EdgeInsets.all(0),
              decoration: BoxDecoration(
                color: kWhite,
                borderRadius: BorderRadius.circular(12.0),
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withOpacity(0.16),
                    blurRadius: 4,
                    offset: Offset(0, 1),
                  ),
                ],
              ),
              child: widget.child,
            ),
          ],
        ),
      ),
    );
  }
}

Edit2:所以我认为问题很可能与我使用的插件有关:persistent_bottom_nav_bar。所以我想这里的任何答案都不能解决我的问题。不过,我将挽歌一些答案作为最好的答案。

【问题讨论】:

  • 请提供一些可重现的代码!!!否则我们帮不了你
  • @LonelyWolf ok 添加它,如果它有什么不同的话

标签: flutter dart flutter-layout


【解决方案1】:

这里的技巧是在您正在使用的任何 ListView 上使用 reverse 参数。

为了不在表格的末尾开始,只在键盘打开时让它反转也很有用,为此我个人使用包keyboard_visibility。

这是一个工作示例:

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

main() => runApp(MaterialApp(
  home: Scaffold(
    body: MyForm(),
  ),
));

class MyForm extends StatefulWidget {
  MyForm() : super();

  @override
  State<StatefulWidget> createState() => MyFormState();
}

class MyFormState extends State<MyForm> {
  bool isKeyboardVisible = false;

  @override
  void initState() {
    super.initState();

    KeyboardVisibilityNotification().addNewListener(
      onChange: (bool visible) {
        if (!visible) {
          setState(() {
            FocusScope.of(context).unfocus();
          });
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(20.0, 20, 20, 0),
      child: SingleChildScrollView(
        reverse: isKeyboardVisible ? true : false,
        child: Padding(
          padding: const EdgeInsets.fromLTRB(0, 0, 0, 100),
          child: Column(
            children: <Widget>[
              for (int i=0; i<100; i++) TextField()
            ],
          ),
        ),
      ),
    );
  }
}

【讨论】:

  • 你“pub get”了吗?
  • 这里是包,他们告诉你如何获取它并导入它:pub.dev/packages/keyboard_visibility
  • 是的,我添加了错误的包。这无论如何都行不通
  • 你能说得更具体一点吗?它适用于我的机器。
【解决方案2】:

我也有类似的问题。它似乎与 viewInsets.bottom 未更新有关(即使键盘显示它也始终为 0)。 这是我的 sn-p:

  @override
  Widget build(BuildContext context) {
    final _keyboardBottomInset = MediaQuery.of(context).viewInsets.bottom;
    final _screenHeight = MediaQuery.of(context).size.height;
    print(
        "Bottom inset is -> $_keyboardBottomInset and height: $_screenHeight");

    return Scaffold(
        body: SingleChildScrollView(
            child: TextFormField(
      initialValue: 'eventday',
      minLines: 20,
      maxLines: 20,
    )));
  }

奇怪的是,当我从一个旧项目运行它时,完全相同的代码仍然有效。我打开的bug是this。

【讨论】:

    猜你喜欢
    • 2022-08-07
    • 1970-01-01
    • 2020-09-28
    • 2020-10-02
    • 2020-06-22
    • 1970-01-01
    • 2021-07-27
    • 2019-03-08
    • 1970-01-01
    相关资源
    最近更新 更多