前言
-
Flutter应用嵌入WebView,实际是将原生平台的WebView嵌入到Flutter的视图中,官方有推出封装插件
webview_flutter
,但功能偏少,就连安卓平台上响应H5的文件选择input标签都没有处理,这个问题在原生应用也是有的,需要开发者自己解决的,那么如果基于官方的webview_flutter
插件去修改的话,太麻烦了 -
所以,我使用的是另外一个第三方插件
flutter_inappwebview
,这个插件就处理了上面安卓平台的问题,功能还比官方的多很多 -
插件库地址
效果展示
WebView页面.png依赖
flutter_inappwebview: ^5.7.2+3
首页
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_view/browser_page.dart';
void main() {
_transparentStatusBar();
runApp(const MyApp());
}
/// 透明状态栏
void _transparentStatusBar() {
if (!kIsWeb) {
//Android平台 透明状态栏
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebView',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter WebView Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return const Center(
child: BrowserPage("https://uniapp.dcloud.io/"),
);
}
}
WebView页面
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'dart:async';
/// App内部Web浏览器页面
class BrowserPage extends StatefulWidget {
const BrowserPage(this.url, {Key? key}) : super(key: key);
final String url;
@override
State createState() => _BrowserPageState();
}
/// 生成进度条组件,进度从0 ~ 1
_createProgressBar(double progress, BuildContext context) {
return LinearProgressIndicator(
backgroundColor: Colors.white70.withOpacity(0),
value: progress == 1.0 ? 0 : progress,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.blue),
);
}
class _BrowserPageState extends State<BrowserPage> {
InAppWebViewController? _webViewController;
String? _webTitle;
double _progress = 0;
bool isCanGoBack = false;
bool isCanForward = false;
final InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
mediaPlaybackRequiresUserGesture: false,
),
/// android 支持HybridComposition
android: AndroidInAppWebViewOptions(
useHybridComposition: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
);
Future<String?> getUrl() {
if (_webViewController == null) {
return Future.sync(() => null);
}
return _webViewController!.getUrl().then((uri) => uri.toString());
}
Future<void> loadUrl(String url) {
if (_webViewController == null) {
return Future.sync(() => null);
}
return _webViewController!
.loadUrl(urlRequest: URLRequest(url: Uri.parse(url)));
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
Future<bool> canGoBack = _webViewController!.canGoBack();
return canGoBack.then((isCanGoBack) {
if (isCanGoBack) {
_webViewController!.goBack();
return false;
} else {
return true;
}
});
},
child: Scaffold(
appBar: AppBar(
leading: Row(
children: [
isCanGoBack
? IconButton(
onPressed: () {
_webViewController?.goBack();
},
icon: const Icon(Icons.arrow_back))
: IconButton(
icon: const Icon(Icons.close),
onPressed: () {
SystemNavigator.pop();
})
],
),
title: Text(_webTitle ?? "FlutterWebView"),
),
body: Column(
children: [
Expanded(
child: Stack(
children: [
InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
initialOptions: options,
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
},
onTitleChanged:
(InAppWebViewController controller, String? title) {
setState(() {
_webTitle = title ?? "";
});
},
onLoadStop: (InAppWebViewController controller, Uri? url) {
//页面加载完毕,显示隐藏AppBar的返回键
controller.canGoBack().then((canGoBack) => {
setState(() {
isCanGoBack = canGoBack;
})
});
controller.canGoForward().then((canForward) => {
setState(() {
isCanForward = canForward;
})
});
},
onProgressChanged:
(InAppWebViewController controller, int progress) {
//进度从0 ~ 100
setState(() {
_progress = progress / 100.0;
});
},
),
_createProgressBar(_progress, context)
],
))
],
),
));
}
}
网友评论