问题描述
我做了一个扑朔迷离的项目,其中我面临着两页的问题。
用于两页的插件-https://pub.dev/packages/flutter_inappwebview
一个页面(即“单个应用程序页面”)呈现了一个网页,并且 WillPopScope在这里正常工作。
另一个名为“比较应用程序页面”的页面将不同的网页呈现到不同的标签页中,而WillPopScope在这里仅适用于第一个标签页,而不适用于标签的其余部分。
我想为每个选项卡实现WillPopScope,以使每个选项卡都有其自己的历史记录,以及当某人出现在特定选项卡上并点击返回按钮时(我要执行此内置后退按钮,而不是通过创建后退按钮)将他带回历史记录。
注意:Single&Compare应用程序中的子控件都使用通用的控件。
下面是主要代码
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();
}
},child: Icon(Icons.arrow_forward),onPressed: () {
if (controller != null) {
controller.goForward();
}
},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(),