我正在尝试将webview_flutter
WebView
连接到BottomNavigationBar
。
我希望在每次点击选项卡时都使用新的URL重新加载视图。在
onTap
回调程序将_currentUrl
更新为新的URL,并使用新的标签索引调用设置状态。
为什么标签栏会更新,但Web视图不会重建? 我想念什么?
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;
});
},
),
),
);
}
}
答案 0 :(得分:1)
您可以使用WebView的WebViewController更改Webview的网址
将以下代码添加到您的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的问题在于将重新构建整个Widget / Page,包括WebView的实例,但是您只想更改当前WebView会话中的url ...
答案 1 :(得分:0)
感谢Joel的评论
是的,发布跨平台框架和基本组件只能在一个平台上工作是很奇怪的,但是,希望他们能够修复到十月份,直到他们在github上感到悲伤为止。
我检查了我的帖子,WebView应该加载新的URL。我忘记的是在导航的void Start()
{
//create your materials
var yourMaterials = new Material[] { Mat1, Mat2 };
//assign it
go.GetComponent<Renderer>().materials = yourMaterials ;
}
处理程序中更新_currentTabIndex
。
但是无论如何:我举了一个简短的例子说明你的情况。对我来说很好...
onTap
请注意,我在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;
});
},
),
);
}
}
处理程序的末尾调用了setState()
,该处理程序重建了页面,但是很遗憾,WebView不会重新初始化!我以为一定是这样,但是颤动一定是在某种程度上处理了这个问题……
还要注意,我将您的onTap
变量从您的_currentTabIndex
类移到了其上级父类WebViewState
。问题是,如果您通过WebViewApp
重建页面,则setState()
始终将初始化为0。出于教程的缘故,我只是将其向上移动,但也许可以将其用作全局参数。
但是,是的,WebView仍然有点令人困惑,并且iOS和Android WebView套件之间有很多差异(归根结底,颤抖的WebView只是当前本机WebView套件的包装)。 / p>
我希望这会有所帮助,祝你好运!