Flutter GestureDetector не вызывает функцию в выражении if else

#flutter #dart

#flutter #dart

Вопрос:

onPanUpdate предполагается, что она вызывается при isEnabled значении true . Но когда isEnabled имеет значение true, onPanUpdate не вызывается. Буду признателен за любую помощь.

 import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Test(),
    );
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  var offset = Offset.zero;
  bool isEnabled = false;

  void onPanUpdate(DragUpdateDetails details) {
    offset  = details.delta;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Transform.translate(
          offset: offset,
          child: Listener(
            onPointerDown: (event) {
              setState(() {
                isEnabled = true;
              });
            },
            onPointerUp: (event) {
              setState(() {
                isEnabled = false;
              });
            },
            child: GestureDetector(
              onPanUpdate: isEnabled ? (d) => onPanUpdate(d) : null,
              child: Container(
                height: 200,
                width: 300,
                color: Colors.red,
              ),
            ),
          ),
        ),
      ),
    );
  }
}
 

Комментарии:

1. попробуйте переименовать onPanUpdate(d) и изменить значение с null на (d) {}

2. Это работает, если я изменяю null на (d) {} , это работает. Но почему это не работает, если я установлю для него значение null? @DungNgo

3. я снова пробую ваш код, и он отлично работает для меня. Можете ли вы проверить, правильно ли вы выполнили действие onPanUpdate?

4. onPanUpdate работает правильно. Как вы сказали, если я изменю значение null на (d) {} , то это сработает. Но установка значения null не работает.

5. Рад, что это работает для вас. Что касается того, почему установка для него значения null не работает, я, честно говоря, не помню. Просто однажды я столкнулся с ошибкой, когда я установил значение null в свой onTap(), а когда я изменил его на () {} , он работал нормально.

Ответ №1:

@DungNgo правильно говорит, что установка onPanUpdate в значение null вызывает эту проблему.

Что касается причин, позвольте мне попытаться объяснить:

При первой сборке, когда onPanUpdate было null, потому isEnabled что равно false , GestureDetector не создавал PanGestureRecognizer .

 class GestureDetector extends StatelessWidget {
 Widget build(BuildContext context) {
  if (onPanDown != null ||
        onPanStart != null ||
        onPanUpdate != null ||
        onPanEnd != null ||
        onPanCancel != null) {
      gestures[PanGestureRecognizer] = GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
        () => PanGestureRecognizer(debugOwner: this),
        (PanGestureRecognizer instance) {
          instance
            ..onDown = onPanDown
            ..onStart = onPanStart
            ..onUpdate = onPanUpdate
            ..onEnd = onPanEnd
            ..onCancel = onPanCancel
            ..dragStartBehavior = dragStartBehavior;
        },
      );
    }
  }
  return RawGestureDetector(
    gestures: gestures,
    behavior: behavior,
    excludeFromSemantics: excludeFromSemantics,
    child: child,
  );
}
 

При нажатии пальца Listener выполняется onPointerDown обратный вызов, устанавливается isEnabled значение true и обновляется пользовательский интерфейс.

На этом этапе GestureDetector выполняется вторая сборка, на этот раз onPanUpdate не имеет значения null, и PanGestureRecognizer создается.

Однако, если у вас есть какое-либо представление о событии жеста с помощью Flutter, вы будете знать, что жест должен быть добавлен в область жестов для распознавания, и жест должен быть распознан для запуска соответствующего обратного вызова.

Это дополнение добавляется в следующем OnPointerDown после создания средства распознавания жестов.

 class RawGestureDetectorState extends State<RawGestureDetector> {
  void _handlePointerDown(PointerDownEvent event) {
    assert(_recognizers != null);
    for (final GestureRecognizer recognizer in _recognizers!.values)
      recognizer.addPointer(event);
  }
  
  @override
  Widget build(BuildContext context) {
    Widget result = Listener(
      onPointerDown: _handlePointerDown,
      behavior: widget.behavior ?? _defaultBehavior,
      child: widget.child,
    );
    if (!widget.excludeFromSemantics)
      result = _GestureSemantics(
        child: result,
        assignSemantics: _updateSemanticsForRenderObject,
      );
    return resu<
  }
}
 

Но в зависимости от вашего кода onPointerUp установит для IsEnabled значение false .

В результате жесты никогда не добавляются на арену/

Поэтому он никогда не вызывается onPanUpdate .

надеюсь, полезно ^_^