I'm using a gesture detector to do 2 different things:
- onTap: record audio for a fixed 10 seconds
- on long press: record audio until the user releases the button, up to a maximum of 10 seconds
Long pressing the button is working fine, but when I do a regular tap my Logcat says that it's running both the regular tap recording and the long press recording. Why can't it differentiate between the two types of taps?
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 after doing a single regular tap and waiting until the whole 10 seconds is up:
##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)
CodePudding user response:
From the docs of onLongPressDown
which might be the start of a long-press.
It says that the widget calls if it thinks the long press happens which includes tapping the widget.
In the same documentation, if you can see the below line
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.
It says, if you want to track when long press is started, you can use onLongPressStart
instead of onLongPressDown
.
Note: also check onLongPressStart docs
Below is a code which you can paste in dartpad (select flutter project) and try to check the console of how it works
Result when tapped:
on long pressed down
on long press cancel
on tapped
Result when long pressed:
on long pressed down
on long press start
on long pressed up
Code:
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,
),
);
}
}