mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 12:18:25 +00:00
More work on animation views
This commit is contained in:
parent
c0128b88de
commit
2d7f23a2fb
@ -1024,7 +1024,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
}
|
||||
|
||||
override fun showVoiceMessageUI() {
|
||||
binding?.inputBarRecordingView?.show()
|
||||
binding?.inputBarRecordingView?.show(lifecycleScope)
|
||||
binding?.inputBar?.alpha = 0.0f
|
||||
val animation = ValueAnimator.ofObject(FloatEvaluator(), 1.0f, 0.0f)
|
||||
animation.duration = 250L
|
||||
|
@ -12,6 +12,11 @@ import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.isVisible
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ViewInputBarRecordingBinding
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
@ -26,9 +31,7 @@ class InputBarRecordingView : RelativeLayout {
|
||||
private var dotViewAnimation: ValueAnimator? = null
|
||||
private var pulseAnimation: ValueAnimator? = null
|
||||
var delegate: InputBarRecordingViewDelegate? = null
|
||||
private val updateTimerRunnable = Runnable {
|
||||
updateTimer()
|
||||
}
|
||||
private var timerJob: Job? = null
|
||||
|
||||
val lockView: LinearLayout
|
||||
get() = binding.lockView
|
||||
@ -50,9 +53,10 @@ class InputBarRecordingView : RelativeLayout {
|
||||
binding = ViewInputBarRecordingBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
binding.inputBarMiddleContentContainer.disableClipping()
|
||||
binding.inputBarCancelButton.setOnClickListener { hide() }
|
||||
|
||||
}
|
||||
|
||||
fun show() {
|
||||
fun show(scope: CoroutineScope) {
|
||||
startTimestamp = Date().time
|
||||
binding.recordButtonOverlayImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_microphone, context.theme))
|
||||
binding.inputBarCancelButton.alpha = 0.0f
|
||||
@ -69,7 +73,7 @@ class InputBarRecordingView : RelativeLayout {
|
||||
animateDotView()
|
||||
pulse()
|
||||
animateLockViewUp()
|
||||
updateTimer()
|
||||
startTimer(scope)
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
@ -86,6 +90,24 @@ class InputBarRecordingView : RelativeLayout {
|
||||
}
|
||||
animation.start()
|
||||
delegate?.handleVoiceMessageUIHidden()
|
||||
stopTimer()
|
||||
}
|
||||
|
||||
private fun startTimer(scope: CoroutineScope) {
|
||||
timerJob?.cancel()
|
||||
timerJob = scope.launch {
|
||||
while (isActive) {
|
||||
val duration = (Date().time - startTimestamp) / 1000L
|
||||
binding.recordingViewDurationTextView.text = DateUtils.formatElapsedTime(duration)
|
||||
|
||||
delay(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopTimer() {
|
||||
timerJob?.cancel()
|
||||
timerJob = null
|
||||
}
|
||||
|
||||
private fun animateDotView() {
|
||||
@ -129,29 +151,6 @@ class InputBarRecordingView : RelativeLayout {
|
||||
animation.start()
|
||||
}
|
||||
|
||||
private fun updateTimer() {
|
||||
val duration = (Date().time - startTimestamp) / 1000L
|
||||
binding.recordingViewDurationTextView.text = DateUtils.formatElapsedTime(duration)
|
||||
|
||||
if (isAttachedToWindow) {
|
||||
// Make sure there's only one runnable in the handler at a time.
|
||||
removeCallbacks(updateTimerRunnable)
|
||||
|
||||
// Should only update the timer if the view is still attached to the window.
|
||||
// Otherwise, the timer will keep running even after the view is detached.
|
||||
postDelayed(updateTimerRunnable, 500)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
if (isVisible) {
|
||||
// If the view was visible (i.e. recording) when it was detached, start the timer again.
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
fun lock() {
|
||||
val fadeOutAnimation = ValueAnimator.ofObject(FloatEvaluator(), 1.0f, 0.0f)
|
||||
fadeOutAnimation.duration = 250L
|
||||
|
@ -16,6 +16,13 @@ import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ActivityPathBinding
|
||||
import org.session.libsession.snode.OnionRequestAPI
|
||||
@ -182,6 +189,7 @@ class PathActivity : PassphraseRequiredActionBarActivity() {
|
||||
private lateinit var location: Location
|
||||
private var dotAnimationStartDelay: Long = 0
|
||||
private var dotAnimationRepeatInterval: Long = 0
|
||||
private var job: Job? = null
|
||||
|
||||
private val dotView by lazy {
|
||||
val result = PathDotView(context)
|
||||
@ -240,25 +248,36 @@ class PathActivity : PassphraseRequiredActionBarActivity() {
|
||||
addView(dotView)
|
||||
}
|
||||
|
||||
private fun performAnimation() {
|
||||
if (isAttachedToWindow) {
|
||||
expand()
|
||||
|
||||
postDelayed({
|
||||
collapse()
|
||||
postDelayed({
|
||||
performAnimation()
|
||||
}, dotAnimationRepeatInterval)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
postDelayed({
|
||||
performAnimation()
|
||||
}, dotAnimationStartDelay)
|
||||
startAnimation()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
|
||||
stopAnimation()
|
||||
}
|
||||
|
||||
private fun startAnimation() {
|
||||
job?.cancel()
|
||||
job = GlobalScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
while (isActive) {
|
||||
delay(dotAnimationStartDelay)
|
||||
expand()
|
||||
delay(EXPAND_ANIM_DELAY_MILLS)
|
||||
collapse()
|
||||
delay(dotAnimationRepeatInterval)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopAnimation() {
|
||||
job?.cancel()
|
||||
job = null
|
||||
}
|
||||
|
||||
private fun expand() {
|
||||
@ -276,6 +295,10 @@ class PathActivity : PassphraseRequiredActionBarActivity() {
|
||||
val endColor = context.resources.getColorWithID(endColorID, context.theme)
|
||||
GlowViewUtilities.animateShadowColorChange(dotView, startColor, endColor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXPAND_ANIM_DELAY_MILLS = 1000L
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user