Requirements
Recording should start as soon as the button is pressed, rather than after a long press
If ACTION_UP is received after the long-press time, it's a long-press, and the recording is completed
If ACTION_UP is received before the long press time, wait until the button is pressed again
The following patch implements the functionality, but recording only starts after the long-press time if it's a 'hold' action
Subject: [PATCH] feat(audio-recorder): hold to record
Holding the record button starts a recording
releasing the record stops the recording
This streamlines UX for an advanced user,
as it takes the recording process from 2 to 1 taps
---
Index: AnkiDroid/src/main/java/com/ichi2/audio/AudioRecordingController.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/audio/AudioRecordingController.kt b/AnkiDroid/src/main/java/com/ichi2/audio/AudioRecordingController.kt
--- a/AnkiDroid/src/main/java/com/ichi2/audio/AudioRecordingController.kt (revision 8a72fe586cbde02375a0542845d51734c268ed40)
+++ b/AnkiDroid/src/main/java/com/ichi2/audio/AudioRecordingController.kt (date 1714232522230)
@@ -41,6 +41,8 @@
import com.ichi2.anki.multimediacard.fields.IFieldController
import com.ichi2.anki.showThemedToast
import com.ichi2.anki.snackbar.showSnackbar
+import com.ichi2.anki.ui.OnHoldListener
+import com.ichi2.anki.ui.setOnHoldListener
import com.ichi2.anki.utils.elapsed
import com.ichi2.anki.utils.formatAsString
import com.ichi2.audio.AudioRecordingController.RecordingState.AppendToRecording
@@ -189,6 +191,27 @@
Timber.i("primary 'record' button clicked")
controlAudioRecorder()
}
+
+ // if the recorder is in the 'cleared' state
+ // holding the 'record' button should start a recording
+ // releasing the 'record' button should complete the recording
+ recordButton.setOnHoldListener(object : OnHoldListener {
+ override fun onHoldStart(): Boolean {
+ if (state != ImmediatePlayback.CLEARED && state != AppendToRecording.CLEARED) return false
+ Timber.d("holding 'record' button'")
+ controlAudioRecorder()
+ return true
+ }
+
+ override fun onHoldEnd() {
+ Timber.d("finished holding 'record' button'")
+ if (state is ImmediatePlayback) {
+ controlAudioRecorder()
+ } else {
+ saveButton?.performClick()
+ }
+ }
+ })
playAudioButton.setOnClickListener {
Timber.i("play/pause clicked")
Index: AnkiDroid/src/main/java/com/ichi2/anki/ui/OnHoldListener.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/OnHoldListener.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/OnHoldListener.kt
new file mode 100644
--- /dev/null (date 1714232522229)
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/OnHoldListener.kt (date 1714232522229)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2024 David Allison <davidallisongithub@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.ichi2.anki.ui
+
+import android.view.MotionEvent
+import android.view.View
+
+interface OnHoldListener {
+ fun onHoldStart(): Boolean
+ fun onHoldEnd()
+}
+
+fun View.setOnHoldListener(listener: OnHoldListener) {
+ val listenerWrapper = object : View.OnTouchListener, View.OnLongClickListener {
+
+ var isHolding = false
+ override fun onTouch(v: View?, event: MotionEvent?): Boolean {
+ if (event?.action == MotionEvent.ACTION_UP && isHolding) {
+ isHolding = false
+ listener.onHoldEnd()
+ return true
+ }
+ return false
+ }
+
+ override fun onLongClick(v: View?): Boolean {
+ if (listener.onHoldStart()) {
+ isHolding = true
+ }
+ return true
+ }
+ }
+ this.setOnLongClickListener(listenerWrapper)
+ this.setOnTouchListener(listenerWrapper)
+}
I proposed a 'hold to record' feature, but it requires additional work
Requirements Recording should start as soon as the button is pressed, rather than after a long press
ACTION_UP
is received after the long-press time, it's a long-press, and the recording is completedACTION_UP
is received before the long press time, wait until the button is pressed againThe following patch implements the functionality, but recording only starts after the long-press time if it's a 'hold' action