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(),
          ),
        ),