#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? @DungNgo3. я снова пробую ваш код, и он отлично работает для меня. Можете ли вы проверить, правильно ли вы выполнили действие 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
.
надеюсь, полезно ^_^