首页 > 解决方案 > 如何使用 GestureDetector 的 onForcePress 属性?

问题描述

我正在尝试使用 Flutter 中小部件的 onForcePress 属性,例如onForcePressStartonForcePressUpdate等等,GestureDetector但是当我触摸屏幕时它们不会触发它们的回调(尽可能轻或尽可能有力)。我之前用 等实现了我原本相同的代码onPanStartonPanUpdate它按预期工作,只是无法访问我想要的压力信息。

似乎没有调用 GestureForcePress 回调的最小工作示例:

import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        print('onTap triggered');
      },
//      onPanStart: (details) {
//        print('onPanStart triggered with ' + details.toString());
//      },
//      onPanUpdate: (details) {
//        print('onPanUpdate triggered with ' + details.toString());
//      },
      onForcePressStart: (details) {
        print('onForcePressStart triggered with ' + details.toString());
      },
      onForcePressUpdate: (details) {
        print('onForcePressUpdate triggered with ' + details.toString());
      },
      child: Container(
        color: Colors.red,
      ),
    );
  }
}

我知道如果压力小于startPressure,它们不应该触发,默认情况下,小部件的 0 到 1 比例为 0.4 GestureDetector。(我也想知道如何编辑这个startPressure属性,但会作为一个单独的问题提出。)

我正在测试的设备是 Galaxy Note 10+,它可以很容易地向其他应用程序提供压力信息。

标签: flutterflutter-layoutgesturedetector

解决方案


将问题的addAllowedPointer(PointerEvent event)根源追溯到 force_press.dart 中的方法,该方法开始

@override
void addAllowedPointer(PointerEvent event) {
  // If the device has a maximum pressure of less than or equal to 1, it
  // doesn't have touch pressure sensing capabilities. Do not participate
  // in the gesture arena.
  if (event is! PointerUpEvent && event.pressureMax <= 1.0) {
      resolve(GestureDisposition.rejected);
  } else {
      // code for adding ForcePress pointer
  }

说明没有压力传感功能的设备的最大压力 <= 1 的评论是不正确的,我的压力传感设备的最大压力为 1.0(通过检查 PointerDataPackets 在调试时压力首先出现在堆栈中的位置发现)。

我在 force_press.dart 中将其更改为

@override
void addAllowedPointer(PointerEvent event) {
  // If the device has a maximum pressure of less than or equal to 1, it
  // doesn't have touch pressure sensing capabilities. Do not participate
  // in the gesture arena.
  if (event is! PointerUpEvent && event.pressureMax == event.pressureMin) {
      resolve(GestureDisposition.rejected);
  } else {
      // code for adding ForcePress pointer
  }

正如在整个 PointerEvent 文档中所述,没有压力感应功能的设备应该具有pressureMin = 1.0pressureMax = 1.0,并且具有压力感应功能且具有 pressureMin = 1.0, pressureMax = 1.0 的设备与没有压力感应功能的设备无法区分在我能想到的所有用例中,这对我来说很有意义。

对我来说,PointerEvents 似乎对压力不敏感,仅在其 PointerDataPackets 中返回 1.0 的压力,返回 0.0 的 pressureMin 和 1.0 的 pressureMax,因此触发 onForcePress 回调,在手势中击败 onPan竞技场。我不介意这一点,因为我只遇到过压力 = 1.0 的 ForcePresses 的行为等同于没有压力数据的 onPans 的情况,但这对于将来遇到这种情况的人来说可能是个问题?

我认为,最终,非压敏触摸事件应该使用 pressureMin = 1.0 注册,正如文档所述,但我还没有弄清楚如何实现这一点。


推荐阅读