#flutter #dart #webview #future #flutter-cupertino
#флаттер #dart #webview #будущее #flutter-купертино
Вопрос:
Моя цель — создать WebView
приложение с несколькими CupertinoTabViews
, которые при нажатии на каждый из них BottomNavigationBarItem
CupertinoTabScaffold
отображали бы разные WebView
виджеты, содержащие виджеты; pageA
и pageB
.
При запуске приложения первый WebView успешно отображает исходную веб-страницу URL. Однако при нажатии другой кнопки Tab (попытке отобразить другой WebView) выдается необработанное исключение: плохое состояние: будущее уже завершено.
main.dart
class _MyHomePageState extends State<MyHomePage> {
int _currentTabIndex = 0;
PageWeb pageA;
PageWeb pageB;
@override
void initState() {
super.initState();
pageA = new PageWeb(this, ObjectKey(0), "A");
pageB = new PageWeb(this, ObjectKey(1), "B");
}
@override
Widget build(BuildContext context) {
final Widget scaffold = CupertinoTabScaffold(
tabBar: CupertinoTabBar(
currentIndex: _currentTabIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('A')),
BottomNavigationBarItem(
icon: Icon(Icons.photo), title: Text('B')),
],
),
tabBuilder: (context, index) {
CupertinoTabView returnValue;
switch (index) {
case 0:
returnValue = CupertinoTabView(
builder: (context) {
return pageA;
},
);
break;
case 1:
returnValue = CupertinoTabView(
builder: (context) {
return pageB;
},
);
break;
}
return returnValue;
},
);
return scaffold;
}
}
pageweb.dart (класс PageWeb)
final Completer<WebViewController> _controller = Completer<WebViewController>();
class PageWeb extends StatefulWidget {
final delegate;
final ObjectKey key;
final String navTitle;
PageWeb(this.delegate, this.key, this.navTitle);
@override
_PageWebState createState() {
return _PageWebState();
}
}
class _PageWebState extends State<PageWeb> {
bool _isLoading = true;
final cookieManager = WebviewCookieManager();
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(widget.navTitle),
),
child: SafeArea(
child: Container(
child: new WebView(
key: widget.key,
initialUrl: "https://www.google.com/search?q=${widget.navTitle}",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
// Here is the error occurring part.
},
onPageStarted: (String pageUrl) {
setState(() {
_isLoading = true;
});
},
onPageFinished: (String pageUrl) {
setState(() {
_isLoading = false;
});
},
))));
}
}
Необработанное исключение: плохое состояние: будущее уже завершено Ошибка содержит следующую строку:
_controller.complete(webViewController);
Комментарии:
1. Почему ваш контроллер объявлен вне класса?
2. @ChristopherMoore Я буквально «просто» переместил переменную внутри класса и увидел комментарий. Это работает. Спасибо. Мне интересно, почему объявление переменной вне класса вызывает ошибку. Это потому, что объявленная переменная рассматривается как глобальная переменная?
3. Да, это то, что он делает
Ответ №1:
Решение было простым. Переместите _controller
объявление внутри класса.
Комментарии:
1. это работает, но в чем проблема объявить этот контроллер вне класса?