簡體   English   中英

當一個區域在 10 秒內被觸摸 5 次時,如何在 Dart/Flutter 中編碼以啟用我的調試模式

[英]How can I code in Dart / Flutter to enable my debug mode when a region is touched 5 times in 10 seconds

我正在將 Flutter 和 Bloc 模式與 rxdart 一起使用,並希望在我的應用程序中有一個調試模式,就像您在 Android 中啟用開發人員模式一樣,用戶應該在 UI 中觸摸 5 次徽標。 UI 部分非常簡單:

Column _renderLogo(BuildContext context) => new Column(
        children: <Widget>[
          GestureDetector(
            onTap: () => BlocProvider.of(context).debugEnabledSink.add(true), 
            child: Container( ...more logo rendering...

考慮到這一點,我正在尋找一種簡單優雅的方法來在 10 秒內檢測 5 個事件。 當在任何 10 秒時間窗口中沒有檢測到足夠的事件時,整個檢測應重置。

您可以使用偽計時器來實現這一點:

const maxDebugTimerSeconds = 10;
const maxTapCount = 5;

DateTime firstTap;
int tapCount;

void doGestureOnTap() {
  final now = DateTime.now();
  if (firstTap != null && now.difference(firstTap).inSeconds < maxDebugTimerSeconds) {
    tapCount++;
    if (tapCount >= maxTapCount) {
      BlocProvider.of(context).debugEnabledSink.add(true);
    }
  } else {
    firstTap = now;
    tapCount = 0;
  }
}

...

GestureDetector(
  onTap: doGestureOnTap,
  ...
),

這個答案基於上面@pskink 的評論。 我只是把它貼在這里,因為它似乎是解決我的問題的一種非常優雅的方式。 謝謝@pskink

DebugSwitcher 可能不是最好的類名稱,它更像是 TimeWindowEventDetector,但您明白了。


class DebugSwitcher {
  final Duration window;
  final int cnt;
  bool value = false;
  var timeStamps = [];

  DebugSwitcher({this.window = const Duration(seconds: 10), this.cnt = 5});

  call(data, sink) {
    var now = DateTime.now();
    timeStamps.removeWhere((ts) => now.difference(ts) >= window);
    timeStamps.add(now);
    if (timeStamps.length >= cnt) {
      timeStamps = [];
      sink.add(value = !value);
    }
  }
}

比你這樣聽接收器事件:

 _debugEnabledController.stream
        .transform(StreamTransformer.fromHandlers(handleData: DebugSwitcher()))
        .listen(
      (_) {
        _isDebugModeOn.value = true;
        infoInternal.value = 'Enabled Debug Mode';
      },
    );

Sink 定義如下:

  final StreamController<bool> _debugEnabledController =
      StreamController<bool>();

  Sink<bool> get debugEnabledSink => _debugEnabledController.sink;

在 UI 中,代碼如下所示:

 Column _renderLogo(BuildContext context) => new Column(
        children: <Widget>[
          GestureDetector(
            onTap: () => BlocProvider.of(context).debugEnabledSink.add(true),
            child: Container(
              margin: const EdgeInsets.only(top: 10.0, right: 10.0),
              height: 80.0,
              child: Theme.of(context).primaryColorBrightness ==
                      Brightness.light
                  ? new Image.asset('assets/app_icon_light.png', fit: BoxFit.contain)
                  : new Image.asset('assets/app_icon.png', fit: BoxFit.contain),
            ),
          ),
        ],
      );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM