WillPopScope无法在不同选项卡中显示的不同WebView上运行

问题描述

我做了一个扑朔迷离的项目,其中我面临着两页的问题。

用于两页的插件-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(),

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...