#android #flutter #android-studio #navigation
Вопрос:
Я пытаюсь создать приложение webview для своего веб-сайта и использовать следующий стартовый код
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter1',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter1'),
),
body: WebView(
initialUrl: "URL.com",
javascriptMode: JavascriptMode.unrestricted,
),
),
);
}
}
проблема
В то время как приложение открывает страницу, меню навигации (три точки) не реагирует, когда я нажимаю.
Что я могу сделать?
Редактировать
Я также попытался разрешить весь смешанный контент, используя flutter_inappwebview
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter2',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter2'),
),
body: InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse("www.URL.com")),
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
mixedContentMode: AndroidMixedContentMode.MIXED_CONTENT_COMPATIBILITY_MODE
)
),
),
),
);
}
}
Все равно точки не работают.
Комментарии:
1. Где код для навигационного меню? Что вы видите в журналах/chrome inspect?
2. @tomerpacific на самом деле журналы не показывают, что что-то не так
Ответ №1:
у вас должен быть контроллер для вашего меню навигации и веб — просмотра
final Completer<WebViewController> _controller =
Completer<WebViewController>();
затем в вашем методе сборки:
Scaffold(
appBar: AppBar(
title: Text('Webview'),
actions: <Widget>[
NavigationControls(_controller.future),
WebViewMenu(_controller.future),
],
}
),
body: Builder(....)...
это классы из https://pub.dev/packages/webview_flutter/example
class WebViewMenu extends StatelessWidget {
WebViewMenu(this.controller);
final Future<WebViewController> controller;
final CookieManager cookieManager = CookieManager();
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: controller,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> controller) {
if (controller.hasError) {
return Text('Controller has Error');
}
return PopupMenuButton<MenuOptions>(
onSelected: (MenuOptions value) {
switch (value) {
case MenuOptions.showUserAgent:
_onShowUserAgent(controller.data!, context);
break;
case MenuOptions.listCookies:
_onListCookies(controller.data!, context);
break;
case MenuOptions.clearCookies:
_onClearCookies(context);
break;
case MenuOptions.addToCache:
_onAddToCache(controller.data!, context);
break;
case MenuOptions.listCache:
_onListCache(controller.data!, context);
break;
case MenuOptions.clearCache:
_onClearCache(controller.data!, context);
break;
case MenuOptions.navigationDelegate:
_onNavigationDelegateExample(controller.data!, context);
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
PopupMenuItem<MenuOptions>(
value: MenuOptions.showUserAgent,
child: const Text('Show user agent'),
enabled: controller.hasData,
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.addToCache,
child: Text('Add to cache'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.listCache,
child: Text('List cache'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.clearCache,
child: Text('Clear cache'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.navigationDelegate,
child: Text('Navigation Delegate example'),
),
],
);
},
);
}
void _onShowUserAgent(
WebViewController controller, BuildContext context) async {
// Send a message with the user agent string to the Toaster JavaScript channel we registered
// with the WebView.
await controller.evaluateJavascript(
'Toaster.postMessage("User Agent: " navigator.userAgent);');
}
void _onListCookies(
WebViewController controller, BuildContext context) async {
final String cookies =
await controller.evaluateJavascript('document.cookie');
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(SnackBar(
content: Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Cookies:'),
_getCookieList(cookies),
],
),
));
}
void _onAddToCache(WebViewController controller, BuildContext context) async {
await controller.evaluateJavascript(
'caches.open("test_caches_entry"); localStorage["test_localStorage"] = "dummy_entry";');
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(const SnackBar(
content: Text('Added a test entry to cache.'),
));
}
void _onListCache(WebViewController controller, BuildContext context) async {
await controller.evaluateJavascript('caches.keys()'
'.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
'.then((caches) => Toaster.postMessage(caches))');
}
void _onClearCache(WebViewController controller, BuildContext context) async {
await controller.clearCache();
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(const SnackBar(
content: Text("Cache cleared."),
));
}
void _onClearCookies(BuildContext context) async {
final bool hadCookies = await cookieManager.clearCookies();
String message = 'There were cookies. Now, they are gone!';
if (!hadCookies) {
message = 'There are no cookies.';
}
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(message),
));
}
void _onNavigationDelegateExample(
WebViewController controller, BuildContext context) async {
final String contentBase64 =
base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));
await controller.loadUrl('data:text/html;base64,$contentBase64');
}
Widget _getCookieList(String cookies) {
if (cookies == null || cookies == '""') {
return Container();
}
final List<String> cookieList = cookies.split(';');
final Iterable<Text> cookieWidgets =
cookieList.map((String cookie) => Text(cookie));
return Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: cookieWidgets.toList(),
);
}
}
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewControllerFuture);
final Future<WebViewController> _webViewControllerFuture;
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: _webViewControllerFuture,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
if (snapshot.hasData) {
final bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data!;
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoBack()) {
await controller.goBack();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(
content: Text("No back history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoForward()) {
await controller.goForward();
} else {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
const SnackBar(
content: Text("No forward history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: !webViewReady
? null
: () {
controller.reload();
},
),
],
);
}
return Text('loading navigationControls');
},
);
}
}
Комментарии:
1. Я использовал пример из ссылки, которую вы дали, и, к сожалению, «точки» по-прежнему не отвечают 🙁