Очистка белого ящика без использования 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]);