Merge pull request #2908 from Isira-Seneviratne/postDelayed

Use Handler.postDelayed() extension function.
This commit is contained in:
Bnyro 2023-01-30 13:56:18 +01:00 committed by GitHub
commit c7c9e4d47b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 76 deletions

View File

@ -31,6 +31,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.os.ConfigurationCompat import androidx.core.os.ConfigurationCompat
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.os.postDelayed
import androidx.core.text.parseAsHtml import androidx.core.text.parseAsHtml
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@ -210,9 +211,9 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
PlayerEvent.Background -> { PlayerEvent.Background -> {
playOnBackground() playOnBackground()
// wait some time in order for the service to get started properly // wait some time in order for the service to get started properly
handler.postDelayed({ handler.postDelayed(500) {
activity?.finish() activity?.finish()
}, 500) }
} }
else -> { else -> {
} }
@ -476,10 +477,10 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
channelId, channelId,
true true
) )
handler.postDelayed({ handler.postDelayed(500) {
NavigationHelper.startAudioPlayer(requireContext()) NavigationHelper.startAudioPlayer(requireContext())
killPlayerFragment() killPlayerFragment()
}, 500) }
} }
private fun setFullscreen() { private fun setFullscreen() {

View File

@ -6,6 +6,7 @@ import android.os.Looper
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.os.postDelayed
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
@ -144,7 +145,7 @@ class WatchHistoryFragment : BaseFragment() {
}) })
// add a listener for scroll end, delay needed to prevent loading new ones the first time // add a listener for scroll end, delay needed to prevent loading new ones the first time
Handler(Looper.getMainLooper()).postDelayed({ Handler(Looper.getMainLooper()).postDelayed(200) {
binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener { binding.historyScrollView.viewTreeObserver.addOnScrollChangedListener {
if (!binding.historyScrollView.canScrollVertically(1) && !isLoading) { if (!binding.historyScrollView.canScrollVertically(1) && !isLoading) {
isLoading = true isLoading = true
@ -152,6 +153,6 @@ class WatchHistoryFragment : BaseFragment() {
isLoading = false isLoading = false
} }
} }
}, 200) }
} }
} }

View File

@ -3,6 +3,8 @@ package com.github.libretube.ui.tools
import android.content.Context import android.content.Context
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.Process
import androidx.core.os.postDelayed
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.activities.MainActivity
@ -25,38 +27,32 @@ object SleepTimer {
"" ""
).ifEmpty { return } ).ifEmpty { return }
handler.postDelayed( handler.postDelayed(breakReminderPref.toLong() * 60 * 1000) {
{ var killApp = true
var killApp = true val mainActivity = context as? MainActivity ?: return@postDelayed
val mainActivity = context as? MainActivity ?: return@postDelayed val snackBar = Snackbar.make(
val snackBar = Snackbar.make( mainActivity.binding.root,
mainActivity.binding.root, R.string.take_a_break,
R.string.take_a_break, Snackbar.LENGTH_INDEFINITE
Snackbar.LENGTH_INDEFINITE )
) .setAction(R.string.cancel) {
.setAction(R.string.cancel) { killApp = false
killApp = false
}
snackBar.show()
(0..REACTION_INTERVAL).forEach {
handler.postDelayed({
val remainingTime = " (${REACTION_INTERVAL - it})"
snackBar.setText(context.getString(R.string.take_a_break) + remainingTime)
}, it * 1000)
} }
handler.postDelayed( snackBar.show()
killApp@{ for (i in 0..REACTION_INTERVAL) {
if (!killApp) return@killApp handler.postDelayed(i * 1000) {
val remainingTime = " (${REACTION_INTERVAL - i})"
// kill the application snackBar.setText(context.getString(R.string.take_a_break) + remainingTime)
mainActivity.finishAffinity() }
mainActivity.finish() }
android.os.Process.killProcess(android.os.Process.myPid()) handler.postDelayed(REACTION_INTERVAL * 1000) {
}, if (killApp) {
REACTION_INTERVAL * 1000 // kill the application
) mainActivity.finishAffinity()
}, mainActivity.finish()
breakReminderPref.toLong() * 60 * 1000 Process.killProcess(Process.myPid())
) }
}
}
} }
} }

View File

@ -14,6 +14,7 @@ import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.os.postDelayed
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import com.github.libretube.R import com.github.libretube.R
@ -90,10 +91,6 @@ internal class CustomExoPlayerView(
if (isControllerFullyVisible) hideController() else showController() if (isControllerFullyVisible) hideController() else showController()
} }
private val hideControllerRunnable = Runnable {
hideController()
}
fun initialize( fun initialize(
playerViewInterface: OnlinePlayerOptions?, playerViewInterface: OnlinePlayerOptions?,
doubleTapOverlayBinding: DoubleTapOverlayBinding, doubleTapOverlayBinding: DoubleTapOverlayBinding,
@ -199,9 +196,7 @@ internal class CustomExoPlayerView(
} }
private fun cancelHideControllerTask() { private fun cancelHideControllerTask() {
runCatching { handler.removeCallbacksAndMessages(HIDE_CONTROLLER_TOKEN)
handler.removeCallbacks(hideControllerRunnable)
}
} }
override fun hideController() { override fun hideController() {
@ -222,7 +217,9 @@ internal class CustomExoPlayerView(
// remove the previous callback from the queue to prevent a flashing behavior // remove the previous callback from the queue to prevent a flashing behavior
cancelHideControllerTask() cancelHideControllerTask()
// automatically hide the controller after 2 seconds // automatically hide the controller after 2 seconds
handler.postDelayed(hideControllerRunnable, AUTO_HIDE_CONTROLLER_DELAY) handler.postDelayed(AUTO_HIDE_CONTROLLER_DELAY, HIDE_CONTROLLER_TOKEN) {
hideController()
}
super.showController() super.showController()
} }
@ -380,8 +377,10 @@ internal class CustomExoPlayerView(
animateSeeking(rewindBTN, rewindIV, rewindTV, true) animateSeeking(rewindBTN, rewindIV, rewindTV, true)
// start callback to hide the button // start callback to hide the button
runnableHandler.removeCallbacks(hideRewindButtonRunnable) runnableHandler.removeCallbacksAndMessages(HIDE_REWIND_BUTTON_TOKEN)
runnableHandler.postDelayed(hideRewindButtonRunnable, 700) runnableHandler.postDelayed(700, HIDE_REWIND_BUTTON_TOKEN) {
rewindBTN.visibility = View.GONE
}
} }
} }
@ -393,8 +392,10 @@ internal class CustomExoPlayerView(
animateSeeking(forwardBTN, forwardIV, forwardTV, false) animateSeeking(forwardBTN, forwardIV, forwardTV, false)
// start callback to hide the button // start callback to hide the button
runnableHandler.removeCallbacks(hideForwardButtonRunnable) runnableHandler.removeCallbacksAndMessages(HIDE_FORWARD_BUTTON_TOKEN)
runnableHandler.postDelayed(hideForwardButtonRunnable, 700) runnableHandler.postDelayed(700, HIDE_FORWARD_BUTTON_TOKEN) {
forwardBTN.visibility = View.GONE
}
} }
} }
@ -438,26 +439,15 @@ internal class CustomExoPlayerView(
.setDuration((ANIMATION_DURATION * 1.5).toLong()) .setDuration((ANIMATION_DURATION * 1.5).toLong())
.withEndAction { .withEndAction {
// move the text back into the button // move the text back into the button
handler.postDelayed({ handler.postDelayed(100) {
textView.animate() textView.animate()
.setDuration(ANIMATION_DURATION / 2) .setDuration(ANIMATION_DURATION / 2)
.translationX(0f) .translationX(0f)
.start() .start()
}, 100) }
} }
} }
private val hideForwardButtonRunnable = Runnable {
doubleTapOverlayBinding?.forwardBTN?.apply {
this.visibility = View.GONE
}
}
private val hideRewindButtonRunnable = Runnable {
doubleTapOverlayBinding?.rewindBTN?.apply {
this.visibility = View.GONE
}
}
private fun initializeGestureProgress() { private fun initializeGestureProgress() {
gestureViewBinding.brightnessProgressBar.let { bar -> gestureViewBinding.brightnessProgressBar.let { bar ->
bar.progress = bar.progress =
@ -701,12 +691,18 @@ internal class CustomExoPlayerView(
// when a control is clicked, restart the countdown to hide the controller // when a control is clicked, restart the countdown to hide the controller
if (isControllerFullyVisible) { if (isControllerFullyVisible) {
cancelHideControllerTask() cancelHideControllerTask()
handler.postDelayed(hideControllerRunnable, AUTO_HIDE_CONTROLLER_DELAY) handler.postDelayed(AUTO_HIDE_CONTROLLER_DELAY, HIDE_CONTROLLER_TOKEN) {
hideController()
}
} }
return super.onInterceptTouchEvent(ev) return super.onInterceptTouchEvent(ev)
} }
companion object { companion object {
private const val HIDE_CONTROLLER_TOKEN = "hideController"
private const val HIDE_FORWARD_BUTTON_TOKEN = "hideForwardButton"
private const val HIDE_REWIND_BUTTON_TOKEN = "hideRewindButton"
private const val SUBTITLE_BOTTOM_PADDING_FRACTION = 0.158f private const val SUBTITLE_BOTTOM_PADDING_FRACTION = 0.158f
private const val ANIMATION_DURATION = 100L private const val ANIMATION_DURATION = 100L
private const val AUTO_HIDE_CONTROLLER_DELAY = 2000L private const val AUTO_HIDE_CONTROLLER_DELAY = 2000L

View File

@ -9,6 +9,7 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.os.postDelayed
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.constants.IntentData import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
@ -74,9 +75,9 @@ object NavigationHelper {
channelId, channelId,
keepQueue keepQueue
) )
handler.postDelayed({ handler.postDelayed(500) {
startAudioPlayer(context) startAudioPlayer(context)
}, 500) }
return return
} }

View File

@ -11,6 +11,7 @@ import android.view.MotionEvent
import android.view.ScaleGestureDetector import android.view.ScaleGestureDetector
import android.view.View import android.view.View
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.os.postDelayed
import com.github.libretube.ui.base.BaseActivity import com.github.libretube.ui.base.BaseActivity
import com.github.libretube.ui.interfaces.PlayerGestureOptions import com.github.libretube.ui.interfaces.PlayerGestureOptions
import com.github.libretube.ui.models.PlayerViewModel import com.github.libretube.ui.models.PlayerViewModel
@ -27,7 +28,7 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
private val elapsedTime get() = SystemClock.elapsedRealtime() private val elapsedTime get() = SystemClock.elapsedRealtime()
private val playerViewModel: PlayerViewModel by activity.viewModels() private val playerViewModel: PlayerViewModel by activity.viewModels()
private val handler: Handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
private val gestureDetector: GestureDetector private val gestureDetector: GestureDetector
private val scaleGestureDetector: ScaleGestureDetector private val scaleGestureDetector: ScaleGestureDetector
@ -110,7 +111,7 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
} }
if (isEnabled && isSecondClick()) { if (isEnabled && isSecondClick()) {
handler.removeCallbacks(runnable) handler.removeCallbacksAndMessages(SINGLE_TAP_TOKEN)
lastDoubleClick = elapsedTime lastDoubleClick = elapsedTime
val eventPositionPercentageX = e.x / width val eventPositionPercentageX = e.x / width
@ -121,8 +122,12 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
} }
} else { } else {
if (recentDoubleClick()) return true if (recentDoubleClick()) return true
handler.removeCallbacks(runnable) handler.removeCallbacksAndMessages(SINGLE_TAP_TOKEN)
handler.postDelayed(runnable, MAX_TIME_DIFF) handler.postDelayed(MAX_TIME_DIFF, SINGLE_TAP_TOKEN) {
// If the last event was for scroll or pinch then avoid single tap call
if (!wasClick || isSecondClick()) return@postDelayed
listener.onSingleTap()
}
lastClick = elapsedTime lastClick = elapsedTime
} }
return true return true
@ -155,12 +160,6 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
return true return true
} }
private val runnable = Runnable {
// If the last event was for scroll or pinch then avoid single tap call
if (!wasClick || isSecondClick()) return@Runnable
listener.onSingleTap()
}
private fun isSecondClick(): Boolean { private fun isSecondClick(): Boolean {
return elapsedTime - lastClick < MAX_TIME_DIFF return elapsedTime - lastClick < MAX_TIME_DIFF
} }
@ -171,6 +170,8 @@ class PlayerGestureController(activity: BaseActivity, private val listener: Play
} }
companion object { companion object {
private const val SINGLE_TAP_TOKEN = "singleTap"
private const val MAX_TIME_DIFF = 400L private const val MAX_TIME_DIFF = 400L
private const val MOVEMENT_THRESHOLD = 30 private const val MOVEMENT_THRESHOLD = 30
private const val BORDER_THRESHOLD = 90 private const val BORDER_THRESHOLD = 90