颤振键盘与resizeToAvoidBottomPadding

时间:2019-08-10 17:07:16

标签: flutter dart flutter-layout

我有一个带有DefaultTabController的页面,该页面是:

 @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        resizeToAvoidBottomPadding: true,
        appBar: AppBar(
            bottom: TabBar(
              indicatorColor: Colors.red,
              indicator: BoxDecoration(
                color: buttonColor,
              ),
              tabs: [Tab(text: "Login"), Tab(text: "Register", key: Key("tabRegistro"))],
            ),
            centerTitle: true,
            title: Text(appBarTitle)),
        body: TabBarView(
          children: [
            new LoginPage(),
            new RegisterPage(),
          ],
        ),
      ),
    );
  }

例如,LoginPage构建为:

@override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomPadding: true,
        key: _scaffoldKey,
        body: SingleChildScrollView(
            child: GestureDetector(
          onTap: () {
            FocusScope.of(context).unfocus();
          },
          child: Center(
            child: Container(
              color: backgroundColor,
              child: Padding(
                  padding: const EdgeInsets.all(36.0),
                  child: Form(
                    key: formKey,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(
                          height: 155.0,
                          child: Image.asset(
                            "assets/images/pet.PNG",
                            fit: BoxFit.contain,
                          ),
                        ),
                        SizedBox(height: 20.0),
                        emailField,
                        SizedBox(height: 10.0),
                        passwordField,
                        SizedBox(height: 20.0),
                        loginButon,
                        SizedBox(height: 20.0),
                        GoogleSignInButton(
                            darkMode: true,
                            text: "Login with Google",
                            onPressed: () {
                              _sigIn();
                            }),
                      ],
                    ),
                  )),
            ),
          ),
        )));
      }

但是,当我写作时,键盘覆盖了文本字段,并且它们不可见。

enter image description here

使用SingleChildScrollView之前可以使用,但是现在不能正常使用了。我尝试放入resizeToAvoidBottomPadding: true,但不起作用。我该怎么做才能解决此问题?

2 个答案:

答案 0 :(得分:0)

代码正常,问题出在Android.manifest.xml。我使用的是Android Simulator,并且为了隐藏状态栏,我将这些行放在了这行:

<script type = "text/javascript" src = "path_to test.js"></script>

如果我把原始行放了,那就行了。原始行是:

android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"

答案 1 :(得分:0)

将每个TextFormField用以下小部件包装

首先创建一个单独的文件,我们将其称为ensure_visible.dart,其中包含:

import 'dart:async';

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';

class EnsureVisibleWhenFocused extends StatefulWidget {
  const EnsureVisibleWhenFocused({
    Key key,
    @required this.child,
    @required this.focusNode,
    this.curve: Curves.ease,
    this.duration: const Duration(milliseconds: 100),
  }) : super(key: key);

  /// The node we will monitor to determine if the child is focused
  final FocusNode focusNode;

  /// The child widget that we are wrapping
  final Widget child;

  /// The curve we will use to scroll ourselves into view.
  ///
  /// Defaults to Curves.ease.
  final Curve curve;

  /// The duration we will use to scroll ourselves into view
  ///
  /// Defaults to 100 milliseconds.
  final Duration duration;

  EnsureVisibleWhenFocusedState createState() => new EnsureVisibleWhenFocusedState();
}

class EnsureVisibleWhenFocusedState extends State<EnsureVisibleWhenFocused> {
  @override
  void initState() {
    super.initState();
    widget.focusNode.addListener(_ensureVisible);
  }

  @override
  void dispose() {
    super.dispose();
    widget.focusNode.removeListener(_ensureVisible);
  }

  Future<Null> _ensureVisible() async {
    // Wait for the keyboard to come into view
    // TODO: position doesn't seem to notify listeners when metrics change,
    // perhaps a NotificationListener around the scrollable could avoid
    // the need insert a delay here.
    await Future.delayed(const Duration(milliseconds: 300));

    if (!widget.focusNode.hasFocus)
      return;

    final RenderObject object = context.findRenderObject();
    final RenderAbstractViewport viewport = RenderAbstractViewport.of(object);
    assert(viewport != null);

    ScrollableState scrollableState = Scrollable.of(context);
    assert(scrollableState != null);

    ScrollPosition position = scrollableState.position;
    double alignment;
    if (position.pixels > viewport.getOffsetToReveal(object, 0.0).offset) {
      // Move down to the top of the viewport
      alignment = 0.0;
    } else if (position.pixels < viewport.getOffsetToReveal(object, 1.0).offset) {
      // Move up to the bottom of the viewport
      alignment = 1.0;
    } else {
      // No scrolling is necessary to reveal the child
      return;
    }
    position.ensureVisible(
      object,
      alignment: alignment,
      duration: widget.duration,
      curve: widget.curve,
    );
  }

  Widget build(BuildContext context) => widget.child;
}

在您的身份验证页面中,只需导入ensure_visible,然后执行以下操作

  • 对于每个TextFormField,您必须像创建FocusNode
  final _usernameFocusNode = FocusNode();
  final _emailFocusNode = FocusNode();

让我们以这种构建方法为例:

  Widget _buildUserNameTextField() {
    return EnsureVisibleWhenFocused(
      focusNode: _usernameFocusNode,
      child: TextFormField(
        focusNode: _usernameFocusNode,
      ),
    );
  }

注意:对于FocusNodeEnsureVisibleWhenFocused,您都必须传递相同的TextFormField