为什么我的按钮 运行 同时有 onTap 功能和 onLongPressDown 功能?
Why does my button run both the onTap function and the onLongPressDown function at the same time?
我正在使用手势检测器来做两件不同的事情:
- onTap:录制固定的 10 秒音频
- 长按:录制音频直到用户松开按钮,最多 10 秒
长按按钮工作正常,但是当我进行常规点击时,我的 Logcat 说它是 运行 常规点击录音和长按录音。为什么不能区分这两种水龙头?
GestureDetector(
onTap: () {
startTapRecording();
setState(() {
sendableMyAppExists = 1;
});
},
onLongPressDown: (details) {
startLongPressRecording();
},
onLongPressUp: () {
stopLongPressRecording();
setState(() {
sendableMyAppExists = 1;
});
startPlaying();
},
),
void startTapRecording() {
print('##MyApp## startTapRecording: 1');
controller?.stop();
controller?.reset();
cancelTimer();
print('##MyApp## startTapRecording: 2');
stopPlaying();
stopRecording();
final String filename = getNewMyAppAudioFileID();
setState(() {
currentMyAppFilename = filename;
});
startRecordingTimer();
print('##MyApp## startTapRecording: 3');
startRecording(MyAppsInProgressFileDir.path + currentMyAppFilename);
controller?.forward();
print('##MyApp## startTapRecording: 4 (finished)');
}
void startLongPressRecording() async {
print('##MyApp## startLongPressRecording: 1');
controller?.stop();
controller?.reset();
cancelTimer();
stopPlaying();
stopRecording();
stopwatch.reset();
stopwatch.start();
final String filename = getNewMyAppAudioFileID();
print('##MyApp## startLongPressRecording: 2');
setState(() {
currentMyAppFilename = filename;
});
startRecordingTimer();
print('##MyApp## startLongPressRecording: 3');
startRecording(MyAppsInProgressFileDir.path + currentMyAppFilename);
controller?.forward();
print('##MyApp## startLongPressRecording: 4 (finished)');
}
void stopLongPressRecording() {
cancelTimer();
stopwatch.stop();
stopRecording();
controller?.stop();
controller?.reset();
setState(() {
sendableMyAppExists = 1;
});
}
Logcat 进行一次常规点击并等待整个 10 秒结束后:
##MyApp## startLongPressRecording: 1
##MyApp## startLongPressRecording: 2
##MyApp## startLongPressRecording: 3
##MyApp## startRecording: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## startLongPressRecording: 4 (finished)
##MyApp## startTapRecording: 1
##MyApp## startTapRecording: 2
##MyApp## startTapRecording: 3
##MyApp## startRecording: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## startTapRecording: 4 (finished)
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## startRecording: 2
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## startRecording: 2
##MyApp## startRecording: 3 (finished)
##MyApp## handleTimeout sendableMyAppExists: 1
##MyApp## runFFMPEGHighLow
##MyApp## initialize: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: file.path = /data/user/0/com.example.MyApp_3/code_cache/MyApp/MyAppAudioFiles/MyAppsInProgress/MyAppAudioFile1
##MyApp## cleanupTempAudioFiles: file.path = /data/user/0/com.example.MyApp_3/code_cache/MyApp/MyAppAudioFiles/MyAppsInProgress/MyAppAudioFile1High.mp3
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## initialize: 2 (finished)
的文档
which might be the start of a long-press.
它说,如果小部件认为发生了长按,包括点击小部件,它就会调用。
在同一文档中,如果您能看到下面一行
If the user completes the long-press, and this gesture wins, onLongPressStart will be called after this callback. Otherwise, onLongPressCancel will be called after this callback.
它说,如果你想在长按开始时跟踪,你可以使用onLongPressStart
而不是onLongPressDown
。
注意:另请查看 onLongPressStart 文档
下面是一段代码,您可以将其粘贴到 dartpad(select flutter 项目)中,并尝试检查其工作原理的控制台
点击时的结果:
on long pressed down
on long press cancel
on tapped
长按结果:
on long pressed down
on long press start
on long pressed up
代码:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => print('on tapped'),
onLongPressUp: () => print('on long pressed up'),
onLongPressDown: (_) => print('on long pressed down'),
onLongPressStart: (_) => print('on long press start'),
onLongPressCancel: () => print('on long press cancel'),
child: Text(
'Tap Me',
style: Theme.of(context).textTheme.headline4,
),
);
}
}
我正在使用手势检测器来做两件不同的事情:
- onTap:录制固定的 10 秒音频
- 长按:录制音频直到用户松开按钮,最多 10 秒
长按按钮工作正常,但是当我进行常规点击时,我的 Logcat 说它是 运行 常规点击录音和长按录音。为什么不能区分这两种水龙头?
GestureDetector(
onTap: () {
startTapRecording();
setState(() {
sendableMyAppExists = 1;
});
},
onLongPressDown: (details) {
startLongPressRecording();
},
onLongPressUp: () {
stopLongPressRecording();
setState(() {
sendableMyAppExists = 1;
});
startPlaying();
},
),
void startTapRecording() {
print('##MyApp## startTapRecording: 1');
controller?.stop();
controller?.reset();
cancelTimer();
print('##MyApp## startTapRecording: 2');
stopPlaying();
stopRecording();
final String filename = getNewMyAppAudioFileID();
setState(() {
currentMyAppFilename = filename;
});
startRecordingTimer();
print('##MyApp## startTapRecording: 3');
startRecording(MyAppsInProgressFileDir.path + currentMyAppFilename);
controller?.forward();
print('##MyApp## startTapRecording: 4 (finished)');
}
void startLongPressRecording() async {
print('##MyApp## startLongPressRecording: 1');
controller?.stop();
controller?.reset();
cancelTimer();
stopPlaying();
stopRecording();
stopwatch.reset();
stopwatch.start();
final String filename = getNewMyAppAudioFileID();
print('##MyApp## startLongPressRecording: 2');
setState(() {
currentMyAppFilename = filename;
});
startRecordingTimer();
print('##MyApp## startLongPressRecording: 3');
startRecording(MyAppsInProgressFileDir.path + currentMyAppFilename);
controller?.forward();
print('##MyApp## startLongPressRecording: 4 (finished)');
}
void stopLongPressRecording() {
cancelTimer();
stopwatch.stop();
stopRecording();
controller?.stop();
controller?.reset();
setState(() {
sendableMyAppExists = 1;
});
}
Logcat 进行一次常规点击并等待整个 10 秒结束后:
##MyApp## startLongPressRecording: 1
##MyApp## startLongPressRecording: 2
##MyApp## startLongPressRecording: 3
##MyApp## startRecording: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## startLongPressRecording: 4 (finished)
##MyApp## startTapRecording: 1
##MyApp## startTapRecording: 2
##MyApp## startTapRecording: 3
##MyApp## startRecording: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## startTapRecording: 4 (finished)
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## startRecording: 2
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## startRecording: 2
##MyApp## startRecording: 3 (finished)
##MyApp## handleTimeout sendableMyAppExists: 1
##MyApp## runFFMPEGHighLow
##MyApp## initialize: 1
##MyApp## cleanupTempAudioFiles: 1
##MyApp## cleanupTempAudioFiles: 2
##MyApp## cleanupTempAudioFiles: file.path = /data/user/0/com.example.MyApp_3/code_cache/MyApp/MyAppAudioFiles/MyAppsInProgress/MyAppAudioFile1
##MyApp## cleanupTempAudioFiles: file.path = /data/user/0/com.example.MyApp_3/code_cache/MyApp/MyAppAudioFiles/MyAppsInProgress/MyAppAudioFile1High.mp3
##MyApp## cleanupTempAudioFiles: 3 (finished)
##MyApp## initialize: 2 (finished)
which might be the start of a long-press.
它说,如果小部件认为发生了长按,包括点击小部件,它就会调用。
在同一文档中,如果您能看到下面一行
If the user completes the long-press, and this gesture wins, onLongPressStart will be called after this callback. Otherwise, onLongPressCancel will be called after this callback.
它说,如果你想在长按开始时跟踪,你可以使用onLongPressStart
而不是onLongPressDown
。
注意:另请查看 onLongPressStart 文档
下面是一段代码,您可以将其粘贴到 dartpad(select flutter 项目)中,并尝试检查其工作原理的控制台
点击时的结果:
on long pressed down
on long press cancel
on tapped
长按结果:
on long pressed down
on long press start
on long pressed up
代码:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => print('on tapped'),
onLongPressUp: () => print('on long pressed up'),
onLongPressDown: (_) => print('on long pressed down'),
onLongPressStart: (_) => print('on long press start'),
onLongPressCancel: () => print('on long press cancel'),
child: Text(
'Tap Me',
style: Theme.of(context).textTheme.headline4,
),
);
}
}