【问题标题】:Flutter device shake iOS pluginFlutter 设备抖动 iOS 插件
【发布时间】:2018-11-26 18:21:39
【问题描述】:

晚安,

我正在考虑为 Flutter 构建一个插件,以检测设备是否在晃动。现在我已经找到了如何在 Swift (Detect shake gesture IOS Swift) 中技术上做到这一点,但我坚持如何将它作为 Flutter 插件连接,因为我无法直接访问视图控制器生命周期事件。

需要一种连接方式

  • viewDidLoad
  • 可以成为第一响应者
  • 运动结束

谁能把我推向正确的方向?

【问题讨论】:

    标签: ios swift plugins flutter flutter-plugin


    【解决方案1】:

    Flutter 团队 已经发布了a plugin called sensors,可用于检测加速度计(和陀螺仪)的运动。

    import 'package:sensors/sensors.dart';
    
    accelerometerEvents.listen((AccelerometerEvent event) {
      // "calculate" "shakes" here
    });
    

    event 包含 xyz 值。将其与时间结合起来,就可以检查是否有晃动。

    我只是指出这一点,因为这比从头开始创建完整插件要少得多。

    【讨论】:

    • 是的,也许那是更好的方法 :-) 感谢您指出这一点!
    【解决方案2】:

    你可以试试这个插件:shake_event

    使用起来非常简单,适用于 iOS 和 Android。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,所以我认为 Reactive ProgrammingRxDart 可以提供帮助。

      您可以创建一个名为sensor_bloc.dartBLoC(业务逻辑组件):

       import 'dart:async';
      import 'dart:math';
      import 'package:rxdart/rxdart.dart';
      import 'package:sensors/sensors.dart';
      
      class SensorBloc {
      
        StreamSubscription<dynamic> _accelerometerStream;
      
        //INPUT
        final _thresholdController = StreamController<int>();
        Sink<int> get threshold => _thresholdController.sink;
      
      
        // OUTPUT
        final  _shakeDetector = StreamController<bool>();
        Stream<bool> get shakeEvent => _shakeDetector.stream.transform(ThrottleStreamTransformer(Duration(seconds: 2)));
      
      
        SensorBloc() {
          const CircularBufferSize = 10;
          double detectionThreshold = 70.0;
      
          List<double> circularBuffer = List.filled(CircularBufferSize,0.0);
          int index = 0;
          double minX=0.0, maxX=0.0;
      
          _thresholdController.stream.listen((value){
            // safety
            if (value > 30) detectionThreshold = value*1.0;
          });
      
          _accelerometerStream =  accelerometerEvents.listen((AccelerometerEvent event){
              index = (index == CircularBufferSize -1 ) ? 0: index+1;
      
              var oldX = circularBuffer[index];
      
              if (oldX == maxX) {
                maxX = circularBuffer.reduce(max);
              }
              if (oldX == minX) {
                minX = circularBuffer.reduce(min);
              }
      
              circularBuffer[index] = event.x;
              if (event.x < minX ) minX=event.x;
              if (event.x> maxX) maxX = event.x;
      
              if (maxX-minX>detectionThreshold)
              {
                _shakeDetector.add(true);
                circularBuffer.fillRange(0, CircularBufferSize, 0.0);
                minX=0.0;
                maxX=0.0;
              }
      
      
          });
      
        }
      
      
      
        void dispose() {
          _shakeDetector.close();
          _accelerometerStream.cancel();
         _thresholdController.close();
        }
      }
      

      然后,只需在您的小部件中订阅其事件: 在你的状态下声明StreamSubscription&lt;bool&gt; shakeSubscriber ;,并挂钩生命周期事件

      (注意:我使用 InheritedWidget 让我可以通过静态函数 MainWidget.bloc(context) 访问伞状 BLoC):

      StreamSubscription<bool> shakeSubscriber ;      
      
      @override
      
        Widget build(BuildContext context) {
      
          if(shakeSubscriber == null ) {
            MainWidget.bloc(context).sensorBloc.shakeEvent.listen((_){
              print("SHAKE ! *************************");
            });
      
          }
      
          return _buildMainScaffold();
        }
      
        @override
        void dispose() {
          if(shakeSubscriber != null ) shakeSubscriber.cancel();
      
          super.dispose();
        }
      

      【讨论】:

        猜你喜欢
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多