如何仅在显示页面时激活位置监听器?

时间:2018-05-05 16:59:11

标签: dart flutter

在特定页面上,进入initState方法我开始听onLocationChanged,就像那样:

_locationSubscription =
    _locationManager.onLocationChanged.listen((Map<String,double> result) {
      setState(() {
        _currentLocation = result;
      });
    });

当我去另一个页面,或者当页面被隐藏时,听众保持actif(我从不称之为“取消”方法......)。我没有找到任何这样做的例子。

我希望根据页面生命周期正确管理启动/停止/重启监听。你能给我这样做的方式吗?

提前谢谢!

3 个答案:

答案 0 :(得分:0)

如果您检查页面路线的isActive,则只有在页面处于活动状态时才可以限制setState()

_locationSubscription =
    _locationManager.onLocationChanged.listen((Map<String,double> result) {
      if(myPageRoute.isActive) {
        setState(() {
          _currentLocation = result;
        });
      }
    });

答案 1 :(得分:0)

您可以使用WidgetsBindingObserver了解何时推送/加入路线。

class AppLifecycleReactor extends StatefulWidget {
  const AppLifecycleReactor({Key key}) : super(key: key);

  @override
  _AppLifecycleReactorState createState() => new _AppLifecycleReactorState();
}

class _AppLifecycleReactorState extends State<AppLifecycleReactor>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  int depth = 0;

  @override
  Future<bool> didPopRoute() async {
    depth--;
    if (depth == 0) {
      // restart listener
    }
    return true;
  }

  @override
  Future<bool> didPushRoute(String route) async {
    depth++;
    // pause listener
    return true;
  }

  @override
  Widget build(BuildContext context) {
    ...
  }
}

答案 2 :(得分:0)

我试用了Firestore数据库和StreamBuilder,并意识到即使列表数据库处于非活动状态,我的列表视图也会从数据库获得更新。因为这会导致不必要的数据通信,所以我最终寻找了解决方案,并且按照[RémiRousselet]的建议使用WidgetsBindingObserver无效。 WidgetBinding源文档声明以下内容:

  

////当系统弹出当前路线时调用。     ///这首先通知绑定的观察者(使用     /// [WidgetsBindingObserver.didPopRoute]),按照注册顺序,直到     ///返回true,

您还可以在实现中看到

  Future<void> handlePopRoute() async {
    for (WidgetsBindingObserver observer in List<WidgetsBindingObserver>.from(_observers)) {
      if (await observer.didPopRoute())
        return;
    }
    SystemNavigator.pop();
  }

迭代将一直进行到其中一个观察者返回true为止,这意味着如果在我们的观察者之前注册了另一个观察者,则该观察者将返回truedidPushRoute()didPushRoute()方法在我们的班级将不会被执行。 我仍在寻找正确的解决方案,一旦找到合适的解决方案,便会更新我的答案。