@@ -5,14 +5,14 @@ import android.graphics.drawable.Drawable
5
5
import android.os.Handler
6
6
import android.os.Looper
7
7
import android.util.AttributeSet
8
- import android.util.SparseBooleanArray
9
8
import android.view.View
10
9
import android.widget.ImageButton
11
10
import android.widget.ProgressBar
12
11
import android.widget.RelativeLayout
13
12
import android.widget.SeekBar
14
13
import android.widget.TextView
15
14
import androidx.annotation.ColorRes
15
+ import androidx.annotation.IdRes
16
16
import androidx.annotation.IntRange
17
17
import androidx.annotation.LayoutRes
18
18
import androidx.media3.common.Timeline
@@ -67,8 +67,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
67
67
var visibilityListener: VideoControlsVisibilityListener ? = null
68
68
69
69
protected var internalListener = InternalListener ()
70
-
71
- protected var enabledViews = SparseBooleanArray ()
70
+ protected val configuration = Configuration ()
72
71
73
72
/* *
74
73
* The delay in milliseconds to wait to start the hide animation
@@ -179,7 +178,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
179
178
timeline.getWindow(timeline.windowCount - 1 , window)
180
179
if (window.isPlaceholder) {
181
180
return onTimelineStyleUpdated(TimelineStyle .UNKNOWN )
182
- } else if (! window.isLive() ) {
181
+ } else if (! window.isLive) {
183
182
return onTimelineStyleUpdated(TimelineStyle .ON_DEMAND )
184
183
}
185
184
@@ -190,7 +189,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
190
189
return onTimelineStyleUpdated(TimelineStyle .UNKNOWN )
191
190
}
192
191
193
- val rollingStart = window.isDynamic || window.isLive()
192
+ val rollingStart = window.isDynamic || window.isLive
194
193
val style = when {
195
194
rollingStart -> TimelineStyle .LIVE
196
195
else -> TimelineStyle .EVENT
@@ -419,7 +418,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
419
418
*/
420
419
fun setPreviousButtonEnabled (enabled : Boolean ) {
421
420
previousButton.isEnabled = enabled
422
- enabledViews.put (R .id.exomedia_controls_previous_btn, enabled)
421
+ configuration.setEnabled (R .id.exomedia_controls_previous_btn, enabled)
423
422
}
424
423
425
424
/* *
@@ -430,7 +429,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
430
429
*/
431
430
fun setNextButtonEnabled (enabled : Boolean ) {
432
431
nextButton.isEnabled = enabled
433
- enabledViews.put (R .id.exomedia_controls_next_btn, enabled)
432
+ configuration.setEnabled (R .id.exomedia_controls_next_btn, enabled)
434
433
}
435
434
436
435
/* *
@@ -471,6 +470,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
471
470
*/
472
471
fun setPreviousButtonRemoved (removed : Boolean ) {
473
472
previousButton.visibility = if (removed) View .GONE else View .VISIBLE
473
+ configuration.setRemoved(R .id.exomedia_controls_previous_btn, removed)
474
474
}
475
475
476
476
/* *
@@ -481,6 +481,7 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
481
481
*/
482
482
fun setNextButtonRemoved (removed : Boolean ) {
483
483
nextButton.visibility = if (removed) View .GONE else View .VISIBLE
484
+ configuration.setRemoved(R .id.exomedia_controls_next_btn, removed)
484
485
}
485
486
486
487
/* *
@@ -739,6 +740,58 @@ abstract class DefaultVideoControls : RelativeLayout, VideoControls, OnTimelineC
739
740
}
740
741
}
741
742
743
+ // TODO: rename to something a bit better...
744
+ protected class Configuration {
745
+ private val itemConfigs = mutableMapOf<Int , ItemConfig >()
746
+
747
+ fun isEnabled (@IdRes id : Int ): Boolean {
748
+ return getViewConfiguration(id)?.enabled ? : true
749
+ }
750
+
751
+ fun setEnabled (@IdRes id : Int , enabled : Boolean ) {
752
+ updateViewConfiguration(id) {
753
+ it.copy(enabled = enabled)
754
+ }
755
+ }
756
+
757
+ fun isRemoved (@IdRes id : Int ): Boolean {
758
+ return getViewConfiguration(id)?.removed ? : false
759
+ }
760
+
761
+ fun setRemoved (@IdRes id : Int , removed : Boolean ) {
762
+ updateViewConfiguration(id) {
763
+ it.copy(removed = removed)
764
+ }
765
+ }
766
+
767
+ /* *
768
+ * Helper function to get the Visibility value for the view with [id]
769
+ */
770
+ fun visibility (@IdRes id : Int ): Int {
771
+ return if (isRemoved(id)) View .GONE else View .VISIBLE
772
+ }
773
+
774
+ private fun getViewConfiguration (@IdRes id : Int ): ItemConfig ? {
775
+ return synchronized(this ) {
776
+ itemConfigs[id]
777
+ }
778
+ }
779
+
780
+ private fun updateViewConfiguration (@IdRes id : Int , action : (ItemConfig ) -> ItemConfig ? ) {
781
+ synchronized(this ) {
782
+ when (val newConfig = action(itemConfigs[id] ? : ItemConfig ())) {
783
+ null -> itemConfigs.remove(id)
784
+ else -> itemConfigs[id] = newConfig
785
+ }
786
+ }
787
+ }
788
+
789
+ private data class ItemConfig (
790
+ val enabled : Boolean = true ,
791
+ val removed : Boolean = false
792
+ )
793
+ }
794
+
742
795
enum class LoadState {
743
796
/* *
744
797
* Occurs when the media content is being prepared for playback. This
0 commit comments