pubspec.yaml
添加webview插件
flutter_webview_plugin: ^0.4.0
webview.dart
基于webview的组件封装
const CATCH_URLS = ['m.ctrip.com/', 'm.ctrip.com/html5/', 'm.ctrip.com/html5'];
class WebView extends StatefulWidget {
final String url;
final String statusBarColor;
final String title;
final bool hideAppBar;
final bool backForbid;
const WebView(
{Key key,
this.url,
this.statusBarColor,
this.title,
this.hideAppBar,
this.backForbid = false})
: super(key: key);
@override
_WebViewState createState() => _WebViewState();
}
class _WebViewState extends State<WebView> {
final webviewReference = FlutterWebviewPlugin();
StreamSubscription<String> _onUrlChanged;
StreamSubscription<WebViewStateChanged> _onStateChanged;
StreamSubscription<WebViewHttpError> _onHttpError;
bool exiting = false;
@override
void initState() {
super.initState();
webviewReference.close();
_onUrlChanged = webviewReference.onUrlChanged.listen((String url) {});
_onStateChanged =
webviewReference.onStateChanged.listen((WebViewStateChanged state) {
switch (state.type) {
case WebViewState.startLoad:
// 如果在白名单
if (_isToMain(state.url) && !exiting) {
// 如果禁用返回功能,则跳转到目标页面
if (widget.backForbid) {
webviewReference.launch(widget.url);
} else {
// 返回上一页面
Navigator.pop(context);
exiting = true;
}
}
break;
default:
break;
}
});
_onHttpError =
webviewReference.onHttpError.listen((WebViewHttpError error) {
print(error);
});
}
/// 是否在白名单里面
_isToMain(String url) {
bool contain = false;
for (final value in CATCH_URLS) {
if (url?.endsWith(value) ?? false) {
contain = true;
break;
}
}
return contain;
}
@override
void dispose() {
_onStateChanged.cancel();
_onUrlChanged.cancel();
_onHttpError.cancel();
webviewReference.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
String statusBarColorStr = widget.statusBarColor ?? 'ffffff';
Color backButtonColor;
if (statusBarColorStr == 'ffffff') {
backButtonColor = Colors.black;
} else {
backButtonColor = Colors.white;
}
return Scaffold(
body: Column(
children: [
_appBar(
Color(int.parse('0xff' + statusBarColorStr)), backButtonColor),
// 填充剩余空间
Expanded(
child: WebviewScaffold(
url: widget.url,
withZoom: true,
withLocalStorage: true,
hidden: true,
initialChild: Container(
color: Colors.white,
child: Center(
child: Text('wating...'),
),
),
))
],
),
);
}
_appBar(Color backgroundColor, Color backButtonColor) {
if (widget.hideAppBar ?? false) {
return Container(
color: backgroundColor,
height: 30,
);
}
return Container(
child: FractionallySizedBox(
widthFactor: 1,
child: Stack(
children: [
// 返回按钮
GestureDetector(
child: Container(
margin: EdgeInsets.only(left: 10),
child: Icon(
Icons.close,
color: backgroundColor,
size: 26,
),
),
),
// 标题
Positioned(
left: 0,
right: 0,
child: Center(
child: Text(
widget.title ?? '',
style: TextStyle(color: backButtonColor, fontSize: 20),
),
),
)
],
),
),
);
}
}
使用
Navigator.push(context, MaterialPageRoute( builder: (context) =>
WebView(
url: model.url,
title: model.title,
statusBarColor: model.statusBarColor,
hideAppBar: model.hideAppBar)));
本文介绍了一个基于Flutter的WebView插件封装方案,该方案通过FlutterWebviewPlugin实现了自定义的WebView组件,支持URL变化监听、状态变更处理等功能,并提供了一个简单的使用示例。
926

被折叠的 条评论
为什么被折叠?



