WillPopScope 不适用于不同选项卡中存在的不同 WebView
WillPopScope not working on different WebView present in different tabs
我做了一个 flutter 项目,其中有两个页面存在问题。
两个页面使用的插件- https://pub.dev/packages/flutter_inappwebview
“单个应用程序页面”的一个页面呈现一个网页,WillPopScope 在这里工作得非常好。
另一个“比较应用程序页面”页面将不同的网页呈现到不同的选项卡,这里 WillPopScope 仅适用于第一个选项卡并且 不适用于选项卡的其余部分 。
我想为每个选项卡实现WillPopScope,这样每个选项卡都有自己的历史记录,当有人出现在特定选项卡上时& 点击后退按钮(我想做这个内置后退按钮而不是通过创建的后退按钮)让他回到历史。
注意 - 单个和比较应用程序中都使用了一个通用小部件作为子项。
下面是主要代码
class NewCompareApp extends StatefulWidget {
@override
_NewCompareAppState createState() => _NewCompareAppState();
}
class _NewCompareAppState extends State<NewCompareApp> {
List apps;
@override
void initState() {
super.initState();
apps = getCompareApps();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: apps.length,
child: Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Card(
elevation: 10,
child: Container(
height: 35,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
padding: EdgeInsets.only(left: 5),
child: TextField(
autofocus: false,
cursorColor: Colors.grey,
decoration: InputDecoration(
hintText: 'Search', border: InputBorder.none),
),
),
),
bottom: TabBar(
indicatorWeight: 1,
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
indicatorColor: Colors.white,
isScrollable: true,
tabs: apps
.map((ca) => Tab(
text: ca.name,
))
.toList(),
),
),
resizeToAvoidBottomInset: false,
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: apps
.map((ca) => WebApp(
url: ca.url,
forWidget: 'cmp',
))
.toList(),
)),
);
}
}
class WebApp extends StatefulWidget {
final String url;
final String forWidget;
WebApp({Key key, @required this.url, @required this.forWidget})
: super(key: key);
@override
_WebAppState createState() => _WebAppState();
}
class _WebAppState extends State<WebApp>
with AutomaticKeepAliveClientMixin<WebApp> {
@override
bool get wantKeepAlive => true;
var currentUrl = '';
InAppWebViewController controller;
Future<bool> _handleBack(context) async {
var status = await controller.canGoBack();
if (status) {
controller.goBack();
} else {
getExitDialog(context, extra: {
"in_app": true,
});
}
return false;
}
@override
Widget build(BuildContext context) {
Widget mainWidget = Column(
children: <Widget>[
Expanded(
child: WillPopScope(
onWillPop: () => _handleBack(context),
child: InAppWebView(
initialUrl: widget.url,
onWebViewCreated: (InAppWebViewController webViewController) {
controller = webViewController;
},
onLoadStart: (InAppWebViewController controller, String url) {
this.currentUrl = url;
},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
horizontalScrollBarEnabled: false,
verticalScrollBarEnabled: false),
),
),
),
),
Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.arrow_back),
onPressed: () => _handleBack(context),
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.refresh),
onPressed: () {
if (controller != null) {
controller.reload();
}
},
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.arrow_forward),
onPressed: () {
if (controller != null) {
controller.goForward();
}
},
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.share),
onPressed: null,
),
],
),
),
],
);
return widget.forWidget == 'single_app'
? Scaffold(body: SafeArea(top: true, child: mainWidget))
: mainWidget;
}
}
代码详细- https://gist.github.com/ycv005/13dec1df2b57535271eb346e132c6775
提前致谢。
经过努力,我找到了以下解决方案,其中一个全局控制器在选项卡上不断变化,并且还有一个本地控制器来处理其他事情。
在底部,选择全局控制器和 TabBarView(用 WillPopScope 包装)
bottom: TabBar(
onTap: (int index) async {
currentIndex = index;
print('here is index- $index');
if (tabWebControllerMap.containsKey(currentIndex)) {
globalController = tabWebControllerMap[currentIndex];
final hereUrl = await globalController.getUrl();
print('here url- $hereUrl');
}
},
controller: _tabController,
indicatorWeight: 1,
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
indicatorColor: Colors.white,
isScrollable: true,
tabs: apps
.map((ca) => Tab(
child: Text(
ca.name,
style: TextStyle(fontSize: 12),
),
))
.toList(),
),
),
我做了一个 flutter 项目,其中有两个页面存在问题。
两个页面使用的插件- https://pub.dev/packages/flutter_inappwebview
“单个应用程序页面”的一个页面呈现一个网页,WillPopScope 在这里工作得非常好。
另一个“比较应用程序页面”页面将不同的网页呈现到不同的选项卡,这里 WillPopScope 仅适用于第一个选项卡并且 不适用于选项卡的其余部分 。
我想为每个选项卡实现WillPopScope,这样每个选项卡都有自己的历史记录,当有人出现在特定选项卡上时& 点击后退按钮(我想做这个内置后退按钮而不是通过创建的后退按钮)让他回到历史。
注意 - 单个和比较应用程序中都使用了一个通用小部件作为子项。
下面是主要代码
class NewCompareApp extends StatefulWidget {
@override
_NewCompareAppState createState() => _NewCompareAppState();
}
class _NewCompareAppState extends State<NewCompareApp> {
List apps;
@override
void initState() {
super.initState();
apps = getCompareApps();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: apps.length,
child: Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Card(
elevation: 10,
child: Container(
height: 35,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
padding: EdgeInsets.only(left: 5),
child: TextField(
autofocus: false,
cursorColor: Colors.grey,
decoration: InputDecoration(
hintText: 'Search', border: InputBorder.none),
),
),
),
bottom: TabBar(
indicatorWeight: 1,
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
indicatorColor: Colors.white,
isScrollable: true,
tabs: apps
.map((ca) => Tab(
text: ca.name,
))
.toList(),
),
),
resizeToAvoidBottomInset: false,
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: apps
.map((ca) => WebApp(
url: ca.url,
forWidget: 'cmp',
))
.toList(),
)),
);
}
}
class WebApp extends StatefulWidget {
final String url;
final String forWidget;
WebApp({Key key, @required this.url, @required this.forWidget})
: super(key: key);
@override
_WebAppState createState() => _WebAppState();
}
class _WebAppState extends State<WebApp>
with AutomaticKeepAliveClientMixin<WebApp> {
@override
bool get wantKeepAlive => true;
var currentUrl = '';
InAppWebViewController controller;
Future<bool> _handleBack(context) async {
var status = await controller.canGoBack();
if (status) {
controller.goBack();
} else {
getExitDialog(context, extra: {
"in_app": true,
});
}
return false;
}
@override
Widget build(BuildContext context) {
Widget mainWidget = Column(
children: <Widget>[
Expanded(
child: WillPopScope(
onWillPop: () => _handleBack(context),
child: InAppWebView(
initialUrl: widget.url,
onWebViewCreated: (InAppWebViewController webViewController) {
controller = webViewController;
},
onLoadStart: (InAppWebViewController controller, String url) {
this.currentUrl = url;
},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
horizontalScrollBarEnabled: false,
verticalScrollBarEnabled: false),
),
),
),
),
Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.arrow_back),
onPressed: () => _handleBack(context),
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.refresh),
onPressed: () {
if (controller != null) {
controller.reload();
}
},
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.arrow_forward),
onPressed: () {
if (controller != null) {
controller.goForward();
}
},
),
FlatButton(
padding: EdgeInsets.zero,
child: Icon(Icons.share),
onPressed: null,
),
],
),
),
],
);
return widget.forWidget == 'single_app'
? Scaffold(body: SafeArea(top: true, child: mainWidget))
: mainWidget;
}
}
代码详细- https://gist.github.com/ycv005/13dec1df2b57535271eb346e132c6775
提前致谢。
经过努力,我找到了以下解决方案,其中一个全局控制器在选项卡上不断变化,并且还有一个本地控制器来处理其他事情。
在底部,选择全局控制器和 TabBarView(用 WillPopScope 包装)
bottom: TabBar(
onTap: (int index) async {
currentIndex = index;
print('here is index- $index');
if (tabWebControllerMap.containsKey(currentIndex)) {
globalController = tabWebControllerMap[currentIndex];
final hereUrl = await globalController.getUrl();
print('here url- $hereUrl');
}
},
controller: _tabController,
indicatorWeight: 1,
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
indicatorColor: Colors.white,
isScrollable: true,
tabs: apps
.map((ca) => Tab(
child: Text(
ca.name,
style: TextStyle(fontSize: 12),
),
))
.toList(),
),
),