我正在尝试将webview_flutter
WebView
连接到BottomNavigationBar
。我希望每当敲击选项卡时,都可以使用新的URL重新加载视图。在onTap
回调我将_currentUrl
更新为新的URL,并使用新的选项卡索引。
为什么选项卡栏会更新但网络视图未重建?我想念什么?
class WebViewApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return WebViewState();
}
}
class WebViewState extends State<WebViewApp> {
int _currentTabIndex = 0;
String _currentUrl = URL.home;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebView Demo',
home: Scaffold(
body: WebView(initialUrl: _currentUrl),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentTabIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('Search'),
),
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today),
title: Text('Profile'),
),
],
onTap: (index) {
switch (index) {
case 0:
_currentUrl = URL.home;
break;
case 1:
_currentUrl = URL.search;
break;
case 2:
_currentUrl = URL.calendar;
break;
}
setState(() {
_currentTabIndex = index;
});
},
),
),
);
}
}
您可以使用WebView的WebViewController更改WebView的URL
将以下代码添加到您的WebView小部件:
body: WebView(
initialUrl: _currentUrl,
onWebViewCreated: (WebViewController webController) {
_webController = webController;
},
),
现在,在将WebViewController提出到WebViewController的实例之后,您可以使用WebViewController的loadUrl((方法更改当前WebView的URL
因此,您可以将ONTAP处理程序的代码更改为以下:
onTap: (index) {
switch (index) {
case 0:
_webController.loadUrl('your_home_url');
break;
case 1:
_webController.loadUrl('your_search_url');
break;
case 2:
_webController.loadUrl('your_calander_url');
break;
}
},
WebViews和SetState的问题是整个小部件/页面将重建,包括WebView的实例,但是您只想在当前的WebView会话中更改URL ...
感谢您的评论Joel
是的,发布crossPlatform框架和基本组件确实在一个平台上起作用是非常奇怪的,但是是的,希望他们能在十月的github上对其进行修复……
我检查了我的帖子,WebView应该加载新的URL。我忘记的是在导航的onTap
处理程序中更新_currentTabIndex
。
但是,无论如何:我为您的情况做了一个快速的例子。它对我来说很好...
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WebView App',
debugShowCheckedModeBanner: false,
home: WebPage(),
);
}
}
class WebPage extends StatefulWidget {
int currentTabIndex = 0;
@override
_WebPageState createState() => _WebPageState();
}
class _WebPageState extends State<WebPage> {
List<String> _urls = [
'https://www.zdf.de/nachrichten/heute/rubrik-politik-100.html',
'https://www.zdf.de/nachrichten/heute/rubrik-wirtschaft-100.html',
'https://www.zdf.de/nachrichten/heute/rubrik-panorama-100.html'
];
WebViewController _webController;
@override
Widget build(BuildContext context) {
print('<----- build init ----->');
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('WebView'),
),
body: WebView(
initialUrl: _urls[widget.currentTabIndex],
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webController) {
_webController = webController;
},
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: widget.currentTabIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.people),
title: Text('Politik')
),
BottomNavigationBarItem(
icon: Icon(Icons.public),
title: Text('Wirtschaft')
),
BottomNavigationBarItem(
icon: Icon(Icons.pie_chart_outlined),
title: Text('Panorama')
)
],
onTap: (selectedIndex) {
_webController.loadUrl(_urls[selectedIndex]);
setState(() {
widget.currentTabIndex = selectedIndex;
});
},
),
);
}
}
请注意,我在onTap
处理程序的末尾调用setState()
,该处理程序重建页面,但却不会初始化WebView!?我认为必须是这种情况,但是Flutter必须在某种程度上或其他方面进行处理...
还要注意,我将您的_currentTabIndex
变量从您的WebViewState
类移动到其上层父级WebViewApp
。问题是,如果您通过setState()
重建页面,_currentTabIndex
将始终用0重新初始化。为了教程的缘故,我只是向上移动它,但是也许您可以将其用作全局参数...
但是,是的,网络浏览量仍然有些混乱,iOS和Android WebView套件之间有很多差异(归根结底,flutter WebView是"仅"当前本机WebView套件的包装器(
我希望这会有所帮助!