Flutter устройство встряхнуть iOS плагин

Вечерние ребята,

Я смотрю на создание плагина для Flutter, который определяет, дрожит ли устройство. Теперь я нашел, как технически сделать это в Swift ( Обнаружение жеста встряхивания IOS Swift), но я застрял на том, как подключить его как плагин Flutter, потому что у меня нет прямого доступа к событиям жизненного цикла контроллера представления.

Нужен способ подключить

  • viewDidLoad
  • canBecomeFirstResponder
  • motionEnded

Кто-нибудь может подтолкнуть меня в правильном направлении?

2 ответа

Решение

Команда Flutter уже опубликовала плагин под названиемsensors, который может быть использован для обнаружения движения от акселерометра (и гироскопа).

import 'package:sensors/sensors.dart';

accelerometerEvents.listen((AccelerometerEvent event) {
  // "calculate" "shakes" here
});

event содержит x, y а также z ценности. Комбинируя это со временем, можно будет проверять наличие сотрясений.

Я просто указываю на это, потому что это гораздо меньше, чем создание полноценного плагина с нуля.

Вы можете попробовать этот плагин: shake_event

С ним довольно просто работать, и он работает как для iOS, так и для Android.

Я столкнулся с той же проблемой, поэтому я решил, Reactive Programming а также RxDart мог бы помочь.

Вы можете создать BLoC (Компонент бизнес-логики) называется sensor_bloc.dart:

 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<bool> shakeSubscriber ; в вашем состоянии, и подключиться к событиям жизненного цикла

(Примечание: я использую InheritedWidget, который дает мне доступ к зонтичному BLoC через статическую функцию MainWidget.bloc(context)):

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();
  }
Другие вопросы по тегам