1

I'm developing application with Flutter and webview_flutter package.

With default configuration I'm getting a white box at bottom of screen.

enter image description here

When I put this code to Scaffold:

resizeToAvoidBottomInset: true

it's disappear:

enter image description here

But in that case Webview not auto resizing when virtual keyboard openned.

enter image description here

If i don't use "resizeToAvoidBottomInset: true" it resizing but white box in the first picture appears.

Is there an another way to clear that white box?

My code:

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,
        );
      })
    );
  }
Erçin Dedeoğlu
  • 4,950
  • 4
  • 49
  • 69

2 Answers2

0

If your app isn't fullscreen then use

    SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
Josteve
  • 11,459
  • 1
  • 23
  • 35
0

If you have a FocusNode attached to the text input widget you use, you can listen to it. Keep a local boolean which you attach to the resizeToAvoidBottomInset parameter of the scaffold. And now when the FocusNode has focus (this is of course not the same as the keyboard showing, but it works) set the parameter to true. You can start a Flutter project with the following 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();
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The GestureDetector Widget in this example makes sure the FocusNode loses focus. And for every other widget that consumes an onTap you also need to programmatically unfocus the FocusNode.

It's not perfect. The user can still dismiss the keyboard without tapping in the app and then the FocusNode doesn't lose focus. So you need to use a package like https://pub.dev/packages/flutter_keyboard_visibility to also listen for that. Of course if that package works well enough you might not need to listen to the FocusNode anymore which will make this easier.

In reality this should all be unnecessary as the Flutter team has to fix this issue (https://github.com/flutter/flutter/issues/23913)

Fleximex
  • 111
  • 9