[Android] Create a repeatable scheduler action and use it for the widgets
Nicolas Pomepuy
git at videolan.org
Tue Jul 25 14:57:29 UTC 2023
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Jul 20 13:55:46 2023 +0200| [20b2ac286ade554af6e0ec19a7c58876273dcc61] | committer: Duncan McNamara
Create a repeatable scheduler action and use it for the widgets
> https://code.videolan.org/videolan/vlc-android/commit/20b2ac286ade554af6e0ec19a7c58876273dcc61
---
.../vlc/gui/dialogs/WidgetExplanationDialog.kt | 41 ++++++++++++----------
.../videolan/vlc/util/LifecycleAwareScheduler.kt | 17 +++++++++
2 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/WidgetExplanationDialog.kt b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/WidgetExplanationDialog.kt
index 96aad7a8e9..f74859bfb4 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/dialogs/WidgetExplanationDialog.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/dialogs/WidgetExplanationDialog.kt
@@ -36,7 +36,6 @@ import android.view.animation.DecelerateInterpolator
import androidx.annotation.DrawableRes
import androidx.core.animation.doOnEnd
import androidx.core.content.ContextCompat
-import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
import org.videolan.tools.coerceInOrDefault
import org.videolan.tools.dp
@@ -44,19 +43,20 @@ import org.videolan.tools.setGone
import org.videolan.tools.setVisible
import org.videolan.vlc.R
import org.videolan.vlc.databinding.DialogWidgetExplanationBinding
-import java.util.Timer
-import java.util.TimerTask
-import kotlin.concurrent.scheduleAtFixedRate
+import org.videolan.vlc.util.LifecycleAwareScheduler
+import org.videolan.vlc.util.SchedulerCallback
-class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
+private const val ACTION_REFRESH = "refresh"
+
+class WidgetExplanationDialog : VLCBottomSheetDialogFragment(), SchedulerCallback {
override fun getDefaultState(): Int = STATE_EXPANDED
override fun needToManageOrientation(): Boolean = true
- private lateinit var timer: TimerTask
private lateinit var resizeAnimation: AnimatorSet
internal lateinit var binding: DialogWidgetExplanationBinding
+ lateinit var scheduler: LifecycleAwareScheduler
private val sizeDrawables = listOf(R.drawable.vlc_widget_mini, R.drawable.vlc_widget_micro, R.drawable.vlc_widget_pill, R.drawable.vlc_widget_macro)
var currentDrawable = R.drawable.vlc_widget_macro
@@ -65,6 +65,10 @@ class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
override fun initialFocusedView(): View = binding.title
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ scheduler = LifecycleAwareScheduler(this)
+ }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = DialogWidgetExplanationBinding.inflate(layoutInflater, container, false)
@@ -73,13 +77,7 @@ class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- timer = Timer().scheduleAtFixedRate(0, 2000) {
- lifecycleScope.launchWhenStarted {
- val nextIndex = (sizeDrawables.indexOf(currentDrawable) + 1).coerceInOrDefault(0, sizeDrawables.size - 1, 0)
- currentDrawable = sizeDrawables[nextIndex]
- displaySizeImage(currentDrawable)
- }
- }
+ scheduler.scheduleAtFixedRate(ACTION_REFRESH, 2000)
val sizeDrawbles = listOf(R.drawable.vlc_widget_mini, R.drawable.vlc_widget_micro, R.drawable.vlc_widget_pill, R.drawable.vlc_widget_macro)
displaySizeImage(sizeDrawbles[0])
@@ -90,7 +88,7 @@ class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
binding.step2.setVisible()
binding.step3.setGone()
animateLongTap()
- timer.cancel()
+ scheduler.cancelAction(ACTION_REFRESH)
}
2 -> {
binding.step1.setGone()
@@ -106,6 +104,16 @@ class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
}
}
+ override fun onTaskTriggered(id: String, data: Bundle) {
+ when (id) {
+ ACTION_REFRESH -> {
+ val nextIndex = (sizeDrawables.indexOf(currentDrawable) + 1).coerceInOrDefault(0, sizeDrawables.size - 1, 0)
+ currentDrawable = sizeDrawables[nextIndex]
+ displaySizeImage(currentDrawable)
+ }
+ }
+ }
+
/**
* Display a new image in the UI showing the different widget sizes
*
@@ -115,11 +123,6 @@ class WidgetExplanationDialog : VLCBottomSheetDialogFragment() {
binding.widgetSizes.setImageDrawable(ContextCompat.getDrawable(requireActivity(), drawable))
}
- override fun dismiss() {
- timer.cancel()
- super.dismiss()
- }
-
/**
* Animate the view showing how to resize a widget
*
diff --git a/application/vlc-android/src/org/videolan/vlc/util/LifecycleAwareScheduler.kt b/application/vlc-android/src/org/videolan/vlc/util/LifecycleAwareScheduler.kt
index 06549cde6f..4c07060afb 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/LifecycleAwareScheduler.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/LifecycleAwareScheduler.kt
@@ -105,6 +105,23 @@ class LifecycleAwareScheduler(private val callback: SchedulerCallback) : Default
timer.schedule(timeTasks[id], delay)
}
+ /**
+ * Schedule an action to be called every [interval]ms.
+ * Can be called in any thread
+ *
+ * @param id the action id
+ * @param interval the interval between each action trigger
+ * @param data the data to be passed
+ */
+ fun scheduleAtFixedRate(id: String, interval: Long, data:Bundle = Bundle()) {
+ callback.lifecycle.addObserver(this at LifecycleAwareScheduler)
+ if (timeTasks.keys.contains(id)) cancelAction(id)
+ timeTasks[id] = timerTask {
+ callback.lifecycleScope.launch(Dispatchers.Main) { callback.onTaskTriggered(id, data) }
+ }
+ timer.scheduleAtFixedRate(timeTasks[id], 0, interval)
+ }
+
/**
* Cancel an existing action
*
More information about the Android
mailing list