Очистка белого ящика без использования resizeToAvoidBottomInset: false

Я разрабатываю приложение с пакетом Flutter и webview_flutter.

В конфигурации по умолчанию я получаю белое поле внизу экрана.

Когда я помещаю этот код в Scaffold:

resizeToAvoidBottomInset: true

это исчезает:

Но в этом случае Webview не изменяет размер автоматически при открытии виртуальной клавиатуры.

Если я не использую "resizeToAvoidBottomInset: true", он меняет размер, но появляется белое поле на первом рисунке.

Есть ли другой способ очистить это белое поле?

Мой код:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  final Completer<WebViewController> _controller =
  Completer<WebViewController>();

  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: null,
      body: Builder(builder: (BuildContext context) {
        return WebView(
          userAgent: "random",
          initialUrl: 'https://www.2harf.com',
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
          },
          onPageStarted: (String url) {
            print('Page started loading: $url');
          },
          onPageFinished: (String url) {
            print('Page finished loading: $url');
          },
          gestureNavigationEnabled: false,
        );
      })
    );
  }

2 ответа

Если у вас есть FocusNode, прикрепленный к виджету ввода текста, который вы используете, вы можете его прослушать. Сохраните локальное логическое значение, которое вы прикрепляете к параметру resizeToAvoidBottomInset скаффолда. И теперь, когда FocusNode имеет фокус (это, конечно, не то же самое, что отображается клавиатура, но он работает), установите для параметра значение true. Вы можете запустить проект Flutter со следующим файлом main.dart:

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setEnabledSystemUIOverlays([]);

  runApp(ResizeWithoutWhitespace());
}

class ResizeWithoutWhitespace extends StatefulWidget {
  @override
  _ResizeWithoutWhitespaceState createState() =>
      _ResizeWithoutWhitespaceState();
}

class _ResizeWithoutWhitespaceState extends State<ResizeWithoutWhitespace> {
  final TextEditingController _controller = TextEditingController();
  final FocusNode _focusNode = FocusNode();

  bool resizeBottom = false;

  @override
  void didChangeDependencies() {
    _focusNode.addListener(_setResizeScaffold);
    super.didChangeDependencies();
  }

  void _setResizeScaffold() {
    setState(() {
      resizeBottom = _focusNode.hasFocus;
    });
  }

  @override
  void dispose() {
    _focusNode.removeListener(_setResizeScaffold);
    _focusNode?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _focusNode.unfocus();
      },
      child: Scaffold(
        resizeToAvoidBottomInset: resizeBottom,
        body: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                margin: EdgeInsets.symmetric(vertical: 32),
                child: Text(
                  'Resize Without Whitespace',
                  textScaleFactor: 1.6,
                ),
              ),
            ),
            TextField(
              focusNode: _focusNode,
              textAlign: TextAlign.center,
              autofocus: false,
              controller: _controller,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                enabledBorder: OutlineInputBorder(),
              ),
            ),
            Container(
              width: double.maxFinite,
              color: Colors.blue,
              padding: EdgeInsets.symmetric(vertical: 32),
              child: RaisedButton(
                child: Text('Button'),
                onPressed: () {
                  print('button pressed');
                  _focusNode.unfocus();
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Виджет GestureDetector в этом примере гарантирует, что FocusNode теряет фокус. И для каждого другого виджета, который потребляет onTap, вам также необходимо программно расфокусировать FocusNode.

Это не идеально. Пользователь по-прежнему может закрыть клавиатуру, не касаясь приложения, и тогда FocusNode не потеряет фокус. Поэтому вам нужно использовать такой пакет, как https://pub.dev/packages/flutter_keyboard_visibility, чтобы также отслеживать это. Конечно, если этот пакет работает достаточно хорошо, возможно, вам больше не понадобится слушать FocusNode, что упростит задачу.

На самом деле в этом нет необходимости, так как команда Flutter должна исправить эту проблему ( https://github.com/flutter/flutter/issues/23913).

Если ваше приложение не полноэкранное, используйте

    SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
Другие вопросы по тегам