flutter - 更改标签控制器索引,等待 Flutter 中的 TabView
问题描述
我正在使用 Flutter 制作一个基于标签栏的简单应用程序。它使用CupertinoTabScaffold
和CupertinoTabBar
。每个CupertinoTabView
都有自己的WebView
.
在第一个TabView
中,放置一个按钮,如果单击所选选项卡将更改为下一个以加载CupertinoTabView
包含WebView
小部件的选项卡,然后导航到某个网站 URL(请注意,该 URL 不是写在上面WebView:initialURL
,而是从第一个标签)。
问题是,当单击按钮时,在更改选定选项卡时,由于未分配控制器而WebView
不会加载特定的URL 。WebView
如何让应用程序“等待”新CupertinoTabView
小部件完全加载?
如果我运行该应用程序,则错误如下:
Unhandled Exception: NoSuchMethodError: The method 'navigateTo' was called on null.
这似乎是因为当单击按钮执行以下代码时,在该行将 tabController.index = tabIndex
生效之前,keyWebPage.curentState.navigateTo
(尚未为空)被调用。
tabController.index = tabIndex;
keyWebPage.currentState.navigateTo(url); //executed 'before' the new TabView initialization
我怀疑这个问题的原因,但无法弄清楚如何解决它。
main.dart
final GlobalKey<PageWebState> keyWebPage = GlobalKey();
class _MyHomePageState extends State<MyHomePage> {
final CupertinoTabController tabController = CupertinoTabController();
int _currentTabIndex = 0;
WebPage pageWeb;
@override
void initState() {
super.initState();
pageWeb = new PageWeb(
this,
key: keyWebPage,
);
}
void navigateTab(int tabIndex, String url) {
setState(() {
_currentTabIndex = tabIndex;
tabController.index = tabIndex;
// HERE is the error occurring part
keyWebPage.currentState.navigateTo(url);
});
}
@override
Widget build(BuildContext context) {
final Widget scaffold = CupertinoTabScaffold(
controller: tabController,
tabBar: CupertinoTabBar(
currentIndex: _currentTabIndex,
onTap: (index) {
setState(() {
_currentTabIndex = index;
});
},
items: const <BottomNavigationBarItem>[
const BottomNavigationBarItem(icon: const Icon(Icons.home), title: Text('Start')),
const BottomNavigationBarItem(icon: const Icon(Icons.web), title: Text('Webpage')),
],
),
tabBuilder: (context, index) {
CupertinoTabView _viewWidget;
switch (index) {
case 0:
_viewWidget = CupertinoTabView(
builder: (context) {
return Center(
child: CupertinoButton(
child: Text('Navigate'),
onPressed: () {
navigateTab(1, 'https://stackoverflow.com/');
},
),
);
},
);
break;
case 1:
_viewWidget = CupertinoTabView(
builder: (context) {
return pageWeb;
},
);
break;
}
return _viewWidget;
},
);
return scaffold;
}
}
网页.dart
final Completer<WebViewController> _controller = Completer<WebViewController>();
class PageWeb extends StatefulWidget {
final delegate;
final ObjectKey key;
PageWeb(this.delegate, this.key);
@override
PageWebState createState() {
return PageWebState();
}
}
void navigateTo(String url) { //Function that will be called on main.dart
controller.future.then((controller) => controller.loadUrl(url));
}
class PageWebState extends State<PageWeb> {
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text("Test"),
),
child: SafeArea(
child: Container(
child: new WebView(
key: widget.key,
initialUrl: "https://www.google.com/",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
))));
}
}
请注意,不考虑使用构造函数传递变量,因为 URL 将被更改,并且单击按钮可以不止一次。
解决方案
推荐阅读
- c# - 正确的 Web 方法响应长度处理
- java - 无法使用 jasypt 加密进行 maven 发布
- c# - 从公共类中的 appsettings.json 文件中获取值
- php - 自定义数组
- openedge - 如何使用progress 4gl计算昨天的记录和今天的记录?
- ruby-on-rails - 设计 Invitable 的 Resque 作业失败 - 未定义的方法 `invitation_instructions' 用于#
Ruby on Rails 项目,我正在运行 Resque 来处理电子邮件(特别是 Devise 和 Devise Invitable)。设计电子邮件发送良好(通过 API 通过邮戳 gem 发送)但 devise_invitable 电子邮件在 Resque 中失败,带有
undefined me
- css - 如何使用 CSS 制作文本并遵循图像大小
- vue.js - 滚动浏览 *.vue 组件文件时,Vim 语法突出显示随机消失
- navigation - 如何聚焦到 AG-Grid 行组件以使用键盘导航
- python - 如何在python中计算一个复杂的函数