将flutter Webview用作主页并按返回按钮将关闭应用程序

我正在尝试使用flift中的Webview作为我的应用程序的主页。一切正常,但是单击“后退”按钮并没有将我发送到Web视图中的上一个网页,而是退出了应用程序。

import 'package:flutter/material.dart';

import 'package:webview_flutter/webview_flutter.dart';

import 'package:url_launcher/url_launcher.dart';

class _StudentPortalState extends State<StudentPortal>{

_launchURL(url) async {

if (await canLaunch(url)) {

await launch(url);

} else {

throw 'Could not launch $url';

}

}

Widget build (BuildContext context){

return Scaffold(

body: WebView(

javascriptMode: JavascriptMode.unrestricted,

initialUrl: 'https://sites.google.com/ttmsa.org/ttmsa/home',

navigationDelegate: (NavigationRequest request) {

if(request.url.contains("intent:")) {

_launchURL('https://forms.gle/XfNbn1Ph9xFdUaKeA');

return NavigationDecision.prevent;

}

return NavigationDecision.navigate;

},

),

);

}

}`

回答:

用WillPopScope包装支架,并在用户单击设备后退按钮时执行WebView Controller goback

代码片段onwillpop

    @override

Widget build(BuildContext context) {

return WillPopScope(

onWillPop: () => _exitApp(context),

child: Scaffold(

appBar: AppBar(

title: const Text('Flutter WebView example'),

// This drop down menu demonstrates that Flutter widgets can be shown over the web view.

actions: <Widget>[

NavigationControls(_controller.future),

SampleMenu(_controller.future),

],

),

退出应用的代码段

WebViewController controllerGlobal;

Future<bool> _exitApp(BuildContext context) async {

if (await controllerGlobal.canGoBack()) {

print("onwill goback");

controllerGlobal.goBack();

return Future.value(true);

} else {

Scaffold.of(context).showSnackBar(

const SnackBar(content: Text("No back history item")),

);

return Future.value(false);

}

}

完整的代码

// Copyright 2018 The Chromium Authors. All rights reserved.

// Use of this source code is governed by a BSD-style license that can be

// found in the LICENSE file.

import 'dart:async';

import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MaterialApp(home: WebViewExample()));

const String kNavigationExamplePage = '''

<!DOCTYPE html><html>

<head><title>Navigation Delegate Example</title></head>

<body>

<p>

The navigation delegate is set to block navigation to the youtube website.

</p>

<ul>

<ul><a href="https://www.youtube.com/">https://www.youtube.com/</a></ul>

<ul><a href="https://www.google.com/">https://www.google.com/</a></ul>

<ul><a href="https://www.google.com/">https://nodejs.org/en</a></ul>

</ul>

</body>

</html>

''';

class WebViewExample extends StatefulWidget {

@override

_WebViewExampleState createState() => _WebViewExampleState();

}

WebViewController controllerGlobal;

Future<bool> _exitApp(BuildContext context) async {

if (await controllerGlobal.canGoBack()) {

print("onwill goback");

controllerGlobal.goBack();

} else {

Scaffold.of(context).showSnackBar(

const SnackBar(content: Text("No back history item")),

);

return Future.value(false);

}

}

class _WebViewExampleState extends State<WebViewExample> {

final Completer<WebViewController> _controller =

Completer<WebViewController>();

@override

Widget build(BuildContext context) {

return WillPopScope(

onWillPop: () => _exitApp(context),

child: Scaffold(

appBar: AppBar(

title: const Text('Flutter WebView example'),

// This drop down menu demonstrates that Flutter widgets can be shown over the web view.

actions: <Widget>[

NavigationControls(_controller.future),

SampleMenu(_controller.future),

],

),

// We're using a Builder here so we have a context that is below the Scaffold

// to allow calling Scaffold.of(context) so we can show a snackbar.

body: Builder(builder: (BuildContext context) {

return WebView(

initialUrl: 'https://flutter.dev',

javascriptMode: JavascriptMode.unrestricted,

onWebViewCreated: (WebViewController webViewController) {

_controller.complete(webViewController);

},

// TODO(iskakaushik): Remove this when collection literals makes it to stable.

// ignore: prefer_collection_literals

javascriptChannels: <JavascriptChannel>[

_toasterJavascriptChannel(context),

].toSet(),

navigationDelegate: (NavigationRequest request) {

if (request.url.startsWith('https://www.youtube.com/')) {

print('blocking navigation to $request}');

return NavigationDecision.prevent;

}

if (request.url.startsWith('https://flutter.dev/docs')) {

print('blocking navigation to $request}');

return NavigationDecision.prevent;

}

print('allowing navigation to $request');

return NavigationDecision.navigate;

},

onPageFinished: (String url) {

print('Page finished loading: $url');

},

);

}),

floatingActionButton: favoriteButton(),

),

);

}

JavascriptChannel _toasterJavascriptChannel(BuildContext context) {

return JavascriptChannel(

name: 'Toaster',

onMessageReceived: (JavascriptMessage message) {

Scaffold.of(context).showSnackBar(

SnackBar(content: Text(message.message)),

);

});

}

Widget favoriteButton() {

return FutureBuilder<WebViewController>(

future: _controller.future,

builder: (BuildContext context,

AsyncSnapshot<WebViewController> controller) {

if (controller.hasData) {

return FloatingActionButton(

onPressed: () async {

final String url = await controller.data.currentUrl();

Scaffold.of(context).showSnackBar(

SnackBar(content: Text('Favorited $url')),

);

},

child: const Icon(Icons.favorite),

);

}

return Container();

});

}

}

enum MenuOptions {

showUserAgent,

listCookies,

clearCookies,

addToCache,

listCache,

clearCache,

navigationDelegate,

}

class SampleMenu extends StatelessWidget {

SampleMenu(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) {

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.

controller.evaluateJavascript(

'Toaster.postMessage("User Agent: " + navigator.userAgent);');

}

void _onListCookies(

WebViewController controller, BuildContext context) async {

final String cookies =

await controller.evaluateJavascript('document.cookie');

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";');

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();

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.';

}

Scaffold.of(context).showSnackBar(SnackBar(

content: Text(message),

));

}

void _onNavigationDelegateExample(

WebViewController controller, BuildContext context) async {

final String contentBase64 =

base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));

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)

: assert(_webViewControllerFuture != null);

final Future<WebViewController> _webViewControllerFuture;

@override

Widget build(BuildContext context) {

return FutureBuilder<WebViewController>(

future: _webViewControllerFuture,

builder:

(BuildContext context, AsyncSnapshot<WebViewController> snapshot) {

final bool webViewReady =

snapshot.connectionState == ConnectionState.done;

final WebViewController controller = snapshot.data;

controllerGlobal = controller;

return Row(

children: <Widget>[

IconButton(

icon: const Icon(Icons.arrow_back_ios),

onPressed: !webViewReady

? null

: () async {

if (await controller.canGoBack()) {

controller.goBack();

} else {

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()) {

controller.goForward();

} else {

Scaffold.of(context).showSnackBar(

const SnackBar(

content: Text("No forward history item")),

);

return;

}

},

),

IconButton(

icon: const Icon(Icons.replay),

onPressed: !webViewReady

? null

: () {

controller.reload();

},

),

],

);

},

);

}

}

工作演示。我单击桌面页面,然后按设备后退按钮,您会看到信息显示“ onwill goback”。并返回上一页

以上是 将flutter Webview用作主页并按返回按钮将关闭应用程序 的全部内容, 来源链接: utcz.com/qa/417326.html

回到顶部