录音取消逻辑
This commit is contained in:
parent
75ab00be93
commit
103a91e7c1
|
|
@ -1,6 +1,7 @@
|
||||||
package com.remax.visualnovel.ui.chat
|
package com.remax.visualnovel.ui.chat
|
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Point
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
|
@ -25,7 +26,6 @@ import com.remax.visualnovel.extension.toast
|
||||||
import com.remax.visualnovel.manager.nim.NimManager
|
import com.remax.visualnovel.manager.nim.NimManager
|
||||||
import com.remax.visualnovel.ui.chat.setting.model.ChatModelDialog
|
import com.remax.visualnovel.ui.chat.setting.model.ChatModelDialog
|
||||||
import com.remax.visualnovel.ui.chat.ui.HoldToTalkDialog
|
import com.remax.visualnovel.ui.chat.ui.HoldToTalkDialog
|
||||||
import com.remax.visualnovel.ui.wallet.manager.WalletManager
|
|
||||||
import com.remax.visualnovel.utils.RecordHelper
|
import com.remax.visualnovel.utils.RecordHelper
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
|
@ -90,13 +90,20 @@ class ChatActivity : BaseBindingActivity<ActivityActorChatBinding>() {
|
||||||
|
|
||||||
private fun initInputPanelEvents() {
|
private fun initInputPanelEvents() {
|
||||||
with(binding.inputPanel) {
|
with(binding.inputPanel) {
|
||||||
holdToTalk({
|
holdToTalk(
|
||||||
|
{
|
||||||
mRecordAssist.startRecording()
|
mRecordAssist.startRecording()
|
||||||
}) {
|
},
|
||||||
|
{
|
||||||
mRecordAssist.stopTalk()
|
mRecordAssist.stopTalk()
|
||||||
|
},
|
||||||
|
touchPosCallback = { point ->
|
||||||
|
mRecordAssist.onTouchPointChanged(point)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查麦克风权限
|
* 检查麦克风权限
|
||||||
|
|
@ -179,6 +186,7 @@ class ChatActivity : BaseBindingActivity<ActivityActorChatBinding>() {
|
||||||
|
|
||||||
inner class RecordAssist {
|
inner class RecordAssist {
|
||||||
|
|
||||||
|
private var mIsCancelled = false
|
||||||
private var recordJob: Job? = null
|
private var recordJob: Job? = null
|
||||||
|
|
||||||
private val recordHelper by lazy {
|
private val recordHelper by lazy {
|
||||||
|
|
@ -210,8 +218,8 @@ class ChatActivity : BaseBindingActivity<ActivityActorChatBinding>() {
|
||||||
private fun startTalk() {
|
private fun startTalk() {
|
||||||
val maxTalkTime = 60
|
val maxTalkTime = 60
|
||||||
val minTalkTime = 1
|
val minTalkTime = 1
|
||||||
|
|
||||||
var recordingProgress = 0
|
var recordingProgress = 0
|
||||||
|
mIsCancelled = false
|
||||||
|
|
||||||
holdToTalkDialog.show()
|
holdToTalkDialog.show()
|
||||||
recordHelper.startRecording(this@ChatActivity, {
|
recordHelper.startRecording(this@ChatActivity, {
|
||||||
|
|
@ -223,6 +231,7 @@ class ChatActivity : BaseBindingActivity<ActivityActorChatBinding>() {
|
||||||
})
|
})
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
|
if (!mIsCancelled) {
|
||||||
if (recordingProgress >= minTalkTime) {
|
if (recordingProgress >= minTalkTime) {
|
||||||
Timber.i("startRecording onStop: ${recordHelper.getFilename()}")
|
Timber.i("startRecording onStop: ${recordHelper.getFilename()}")
|
||||||
|
|
||||||
|
|
@ -237,19 +246,26 @@ class ChatActivity : BaseBindingActivity<ActivityActorChatBinding>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//录音最少1秒
|
showToast(R.string.min_voice_time) //录音最少1秒
|
||||||
showToast(R.string.min_voice_time)
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun stopTalk() {
|
fun stopTalk() {
|
||||||
|
mIsCancelled = holdToTalkDialog.isTouchInCancelArea;
|
||||||
holdToTalkDialog.dismiss()
|
holdToTalkDialog.dismiss()
|
||||||
recordJob?.cancel()
|
recordJob?.cancel()
|
||||||
recordHelper.stopRecording()
|
recordHelper.stopRecording()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onTouchPointChanged(point: Point) {
|
||||||
|
if (holdToTalkDialog.isShowing) {
|
||||||
|
holdToTalkDialog.onTouchPointChanged(point)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package com.remax.visualnovel.ui.chat
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Point
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
|
@ -82,7 +83,7 @@ class InputPanel @JvmOverloads constructor(context: Context, attrs: AttributeSet
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
fun holdToTalk(callback: () -> Unit, cancelCallback: () -> Unit) {
|
fun holdToTalk(callback: () -> Unit, cancelCallback: () -> Unit, touchPosCallback: (point: Point) -> Unit) {
|
||||||
binding.ivHold2talk.run {
|
binding.ivHold2talk.run {
|
||||||
setOnTouchListener { v, event ->
|
setOnTouchListener { v, event ->
|
||||||
when (event.action) {
|
when (event.action) {
|
||||||
|
|
@ -93,10 +94,15 @@ class InputPanel @JvmOverloads constructor(context: Context, attrs: AttributeSet
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
cancelCallback.invoke()
|
cancelCallback.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
touchPosCallback.invoke(Point(event.rawX.toInt(), event.rawY.toInt()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,68 +1,58 @@
|
||||||
package com.remax.visualnovel.ui.chat.ui
|
package com.remax.visualnovel.ui.chat.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Point
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.view.MotionEvent
|
|
||||||
import android.view.View
|
|
||||||
import androidx.annotation.VisibleForTesting
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.remax.visualnovel.R
|
import com.remax.visualnovel.R
|
||||||
import com.remax.visualnovel.databinding.DialogHoldToTalkBinding
|
import com.remax.visualnovel.databinding.DialogHoldToTalkBinding
|
||||||
import com.remax.visualnovel.widget.dialoglib.LBindingDialog
|
import com.remax.visualnovel.widget.dialoglib.LBindingDialog
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by HJW on 2025/8/16
|
|
||||||
*/
|
|
||||||
class HoldToTalkDialog(context: Context) :
|
class HoldToTalkDialog(context: Context) :
|
||||||
LBindingDialog<DialogHoldToTalkBinding>(context, DialogHoldToTalkBinding::inflate) {
|
LBindingDialog<DialogHoldToTalkBinding>(context, DialogHoldToTalkBinding::inflate) {
|
||||||
|
|
||||||
|
var isTouchInCancelArea = false
|
||||||
|
|
||||||
fun build(): HoldToTalkDialog {
|
fun build(): HoldToTalkDialog {
|
||||||
with()
|
with()
|
||||||
setBottom()
|
setBottom()
|
||||||
setBgColorToken(R.string.color_transparent)
|
setBgColorToken(R.string.color_transparent)
|
||||||
setMaskValue(0f)
|
setMaskValue(0f)
|
||||||
initRootTouchEvent()
|
|
||||||
show()
|
show()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initRootTouchEvent() {
|
|
||||||
with(binding.root) {
|
|
||||||
fun onTouchEvent(event: MotionEvent): Boolean {
|
|
||||||
val x = event.x.toInt()
|
|
||||||
val y = event.y.toInt()
|
|
||||||
when (event.actionMasked) {
|
|
||||||
MotionEvent.ACTION_MOVE -> {
|
|
||||||
updateStateUI(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isInValidArea(event: MotionEvent) : Boolean {
|
fun onTouchPointChanged(point: Point) {
|
||||||
val rect = Rect()
|
|
||||||
binding.viewRelease.getHitRect(rect)
|
|
||||||
return rect.contains(event.rawX.toInt(), event.rawY.toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateStateUI(event: MotionEvent) {
|
|
||||||
with (binding) {
|
with (binding) {
|
||||||
when (isInValidArea(event)) {
|
isTouchInCancelArea = !getTouchValidArea().contains(point.x, point.y)
|
||||||
true -> {
|
when (isTouchInCancelArea) {
|
||||||
|
false -> {
|
||||||
viewRelease.setBackgroundResource(R.mipmap.bg_recording_normal)
|
viewRelease.setBackgroundResource(R.mipmap.bg_recording_normal)
|
||||||
cancelHintRoot.isVisible = true
|
cancelHintRoot.isVisible = true
|
||||||
|
tvRelease.text = context.resources.getString(R.string.release_to_send)
|
||||||
}
|
}
|
||||||
|
|
||||||
false -> {
|
true -> {
|
||||||
viewRelease.setBackgroundResource(R.mipmap.bg_recording_cancel)
|
viewRelease.setBackgroundResource(R.mipmap.bg_recording_cancel)
|
||||||
cancelHintRoot.isVisible = false
|
cancelHintRoot.isVisible = false
|
||||||
|
tvRelease.text = context.resources.getString(R.string.release_to_cancel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getTouchValidArea(): Rect {
|
||||||
|
val location = IntArray(2)
|
||||||
|
binding.viewRelease.getLocationOnScreen(location)
|
||||||
|
return Rect(
|
||||||
|
location[0],
|
||||||
|
location[1],
|
||||||
|
location[0] + binding.viewRelease.width,
|
||||||
|
location[1] + binding.viewRelease.height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@
|
||||||
<string name="prompt">Prompt</string>
|
<string name="prompt">Prompt</string>
|
||||||
<string name="heart_member_unlock">Heart member unlock</string>
|
<string name="heart_member_unlock">Heart member unlock</string>
|
||||||
<string name="member_unlock">Member unlock</string>
|
<string name="member_unlock">Member unlock</string>
|
||||||
<string name="release_to_send">Release to send</string>
|
|
||||||
<string name="my_chat_personal">My Chat Personal</string>
|
<string name="my_chat_personal">My Chat Personal</string>
|
||||||
<string name="chat_setting">Chat Setting</string>
|
<string name="chat_setting">Chat Setting</string>
|
||||||
<string name="auto_play_voice">Auto play voice</string>
|
<string name="auto_play_voice">Auto play voice</string>
|
||||||
|
|
@ -466,6 +466,7 @@
|
||||||
<string name="hold_to_talk">Hold to Talk</string>
|
<string name="hold_to_talk">Hold to Talk</string>
|
||||||
<string name="type_msg_hint">Type a message</string>
|
<string name="type_msg_hint">Type a message</string>
|
||||||
<string name="swipe_up_to_cancel">Swipe Up to Cancel</string>
|
<string name="swipe_up_to_cancel">Swipe Up to Cancel</string>
|
||||||
|
<string name="release_to_send">Release to Send</string>
|
||||||
|
<string name="release_to_cancel">Release to Cancel</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue