forked from recloudstream/cloudstream
Redesign player layout for tv (#479)
Co-authored-by: LagradOst <balt.758@gmail.com>
This commit is contained in:
parent
9f9251108a
commit
7185df6b68
11 changed files with 680 additions and 61 deletions
|
@ -37,7 +37,7 @@ object CommonActivity {
|
|||
val onDialogDismissedEvent = Event<Int>()
|
||||
|
||||
var playerEventListener: ((PlayerEventType) -> Unit)? = null
|
||||
var keyEventListener: ((KeyEvent?) -> Boolean)? = null
|
||||
var keyEventListener: ((Pair<KeyEvent?, Boolean>) -> Boolean)? = null
|
||||
|
||||
|
||||
var currentToast: Toast? = null
|
||||
|
@ -134,8 +134,8 @@ object CommonActivity {
|
|||
}
|
||||
}
|
||||
|
||||
fun loadThemes(act: Activity? ) {
|
||||
if(act == null) return
|
||||
fun loadThemes(act: Activity?) {
|
||||
if (act == null) return
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(act)
|
||||
|
||||
val currentTheme =
|
||||
|
@ -323,6 +323,7 @@ object CommonActivity {
|
|||
val nextView = act.findViewById<View?>(next)
|
||||
if (nextView != null) {
|
||||
nextView.requestFocus()
|
||||
keyEventListener?.invoke(Pair(event, true))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +346,7 @@ object CommonActivity {
|
|||
}
|
||||
}
|
||||
|
||||
if (keyEventListener?.invoke(event) == true) {
|
||||
if (keyEventListener?.invoke(Pair(event, false)) == true) {
|
||||
return true
|
||||
}
|
||||
return null
|
||||
|
|
|
@ -58,7 +58,6 @@ const val PRELOAD_NEXT_EPISODE_PERCENTAGE = 80
|
|||
const val NEXT_WATCH_EPISODE_PERCENTAGE = 95
|
||||
|
||||
abstract class AbstractPlayerFragment(
|
||||
@LayoutRes val layout: Int,
|
||||
val player: IPlayer = CS3IPlayer()
|
||||
) : Fragment() {
|
||||
var resizeMode: Int = 0
|
||||
|
@ -66,6 +65,9 @@ abstract class AbstractPlayerFragment(
|
|||
var subView: SubtitleView? = null
|
||||
var isBuffering = true
|
||||
|
||||
@LayoutRes
|
||||
protected var layout: Int = R.layout.fragment_player
|
||||
|
||||
open fun nextEpisode() {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
@ -78,12 +80,12 @@ abstract class AbstractPlayerFragment(
|
|||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
open fun playerDimensionsLoaded(widthHeight : Pair<Int, Int>) {
|
||||
open fun playerDimensionsLoaded(widthHeight: Pair<Int, Int>) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
private fun keepScreenOn(on : Boolean) {
|
||||
if(on) {
|
||||
private fun keepScreenOn(on: Boolean) {
|
||||
if (on) {
|
||||
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
} else {
|
||||
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
|
@ -128,7 +130,7 @@ abstract class AbstractPlayerFragment(
|
|||
}
|
||||
|
||||
// somehow the phone is wacked
|
||||
if(!startedAnimation) {
|
||||
if (!startedAnimation) {
|
||||
player_pause_play?.setImageResource(if (isPlayingRightNow) R.drawable.netflix_pause else R.drawable.netflix_play)
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -56,7 +56,7 @@ const val DOUBLE_TAB_MINIMUM_TIME_BETWEEN = 200L // this also affects the UI
|
|||
const val DOUBLE_TAB_PAUSE_PERCENTAGE = 0.15 // in both directions
|
||||
|
||||
// All the UI Logic for the player
|
||||
open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
|
||||
open class FullScreenPlayer : AbstractPlayerFragment() {
|
||||
// state of player UI
|
||||
protected var isShowing = false
|
||||
protected var isLocked = false
|
||||
|
@ -352,6 +352,7 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
|
|||
}
|
||||
activity?.hideSystemUI()
|
||||
animateLayoutChanges()
|
||||
player_pause_play.requestFocus()
|
||||
}
|
||||
|
||||
private fun toggleLock() {
|
||||
|
@ -413,13 +414,15 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
|
|||
|
||||
private fun updateLockUI() {
|
||||
player_lock?.setIconResource(if (isLocked) R.drawable.video_locked else R.drawable.video_unlocked)
|
||||
val color = if (isLocked) context?.colorFromAttribute(R.attr.colorPrimary)
|
||||
else Color.WHITE
|
||||
if (color != null) {
|
||||
player_lock?.setTextColor(color)
|
||||
player_lock?.iconTint = ColorStateList.valueOf(color)
|
||||
player_lock?.rippleColor =
|
||||
ColorStateList.valueOf(Color.argb(50, color.red, color.green, color.blue))
|
||||
if (layout == R.layout.fragment_player) {
|
||||
val color = if (isLocked) context?.colorFromAttribute(R.attr.colorPrimary)
|
||||
else Color.WHITE
|
||||
if (color != null) {
|
||||
player_lock?.setTextColor(color)
|
||||
player_lock?.iconTint = ColorStateList.valueOf(color)
|
||||
player_lock?.rippleColor =
|
||||
ColorStateList.valueOf(Color.argb(50, color.red, color.green, color.blue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,50 +822,71 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
|
|||
return true
|
||||
}
|
||||
|
||||
private fun handleKeyEvent(event: KeyEvent): Boolean {
|
||||
event.keyCode.let { keyCode ->
|
||||
when (event.action) {
|
||||
KeyEvent.ACTION_DOWN -> {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_DPAD_CENTER, KeyEvent.KEYCODE_DPAD_UP -> {
|
||||
if (!isShowing) {
|
||||
onClickChange()
|
||||
return true
|
||||
private fun handleKeyEvent(event: KeyEvent, hasNavigated: Boolean): Boolean {
|
||||
if (hasNavigated) {
|
||||
autoHide()
|
||||
} else {
|
||||
event.keyCode.let { keyCode ->
|
||||
when (event.action) {
|
||||
KeyEvent.ACTION_DOWN -> {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_DPAD_CENTER -> {
|
||||
if (!isShowing) {
|
||||
if (!isLocked) player.handleEvent(CSPlayerEvent.PlayPauseToggle)
|
||||
onClickChange()
|
||||
return true
|
||||
}
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_UP -> {
|
||||
if (!isShowing) {
|
||||
onClickChange()
|
||||
return true
|
||||
}
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_LEFT -> {
|
||||
if (!isShowing && !isLocked) {
|
||||
player.seekTime(-10000L)
|
||||
return true
|
||||
} else if (player_pause_play?.isFocused == true) {
|
||||
player.seekTime(-30000L)
|
||||
return true
|
||||
}
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||
if (!isShowing && !isLocked) {
|
||||
player.seekTime(10000L)
|
||||
return true
|
||||
} else if (player_pause_play?.isFocused == true) {
|
||||
player.seekTime(30000L)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//println("Keycode: $keyCode")
|
||||
//showToast(
|
||||
// this,
|
||||
// "Got Keycode $keyCode | ${KeyEvent.keyCodeToString(keyCode)} \n ${event?.action}",
|
||||
// Toast.LENGTH_LONG
|
||||
//)
|
||||
}
|
||||
}
|
||||
|
||||
when (keyCode) {
|
||||
// don't allow dpad move when hidden
|
||||
KeyEvent.KEYCODE_DPAD_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||
KeyEvent.KEYCODE_DPAD_UP,
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN_RIGHT,
|
||||
KeyEvent.KEYCODE_DPAD_UP_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_UP_RIGHT -> {
|
||||
if (!isShowing) {
|
||||
return true
|
||||
} else {
|
||||
autoHide()
|
||||
when (keyCode) {
|
||||
// don't allow dpad move when hidden
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||
KeyEvent.KEYCODE_DPAD_UP,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN_RIGHT,
|
||||
KeyEvent.KEYCODE_DPAD_UP_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_UP_RIGHT -> {
|
||||
if (!isShowing) {
|
||||
return true
|
||||
} else {
|
||||
autoHide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// netflix capture back and hide ~monke
|
||||
KeyEvent.KEYCODE_BACK -> {
|
||||
if (isShowing) {
|
||||
onClickChange()
|
||||
return true
|
||||
// netflix capture back and hide ~monke
|
||||
KeyEvent.KEYCODE_BACK -> {
|
||||
if (isShowing) {
|
||||
onClickChange()
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -940,12 +964,11 @@ open class FullScreenPlayer : AbstractPlayerFragment(R.layout.fragment_player) {
|
|||
}
|
||||
|
||||
// handle tv controls directly based on player state
|
||||
keyEventListener = { keyEvent ->
|
||||
if (keyEvent != null) {
|
||||
handleKeyEvent(keyEvent)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
keyEventListener = { eventNav ->
|
||||
val (event, hasNavigated) = eventNav
|
||||
if (event != null)
|
||||
handleKeyEvent(event, hasNavigated)
|
||||
else false
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
|||
import com.lagradost.cloudstream3.mvvm.observe
|
||||
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
|
||||
import com.lagradost.cloudstream3.ui.result.ResultEpisode
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||
|
@ -279,7 +280,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
sourceDialog.dismissSafe(activity)
|
||||
}
|
||||
}
|
||||
} catch (e : Exception) {
|
||||
} catch (e: Exception) {
|
||||
logError(e)
|
||||
}
|
||||
}
|
||||
|
@ -485,6 +486,10 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// this is used instead of layout-television to follow the settings and some TV devices are not classified as TV for some reason
|
||||
layout =
|
||||
if (context?.isTvSettings() == true) R.layout.fragment_player_tv else R.layout.fragment_player
|
||||
|
||||
viewModel = ViewModelProvider(this)[PlayerGeneratorViewModel::class.java]
|
||||
viewModel.attachGenerator(lastUsedGenerator)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
|
5
app/src/main/res/color/player_button_tv.xml
Normal file
5
app/src/main/res/color/player_button_tv.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true" android:color="#FFFFFF"/>
|
||||
<item android:color="#33FFFFFF"/>
|
||||
</selector>
|
5
app/src/main/res/color/player_on_button_tv.xml
Normal file
5
app/src/main/res/color/player_on_button_tv.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true" android:color="@color/black"/>
|
||||
<item android:color="@color/white"/>
|
||||
</selector>
|
15
app/src/main/res/drawable/player_button_tv.xml
Normal file
15
app/src/main/res/drawable/player_button_tv.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<corners android:radius="3dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#33FFFFFF" />
|
||||
<corners android:radius="3dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
26
app/src/main/res/drawable/player_gradient_tv.xml
Normal file
26
app/src/main/res/drawable/player_gradient_tv.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#000000"
|
||||
android:centerColor="#00000000"
|
||||
android:endColor="#00000000"
|
||||
android:centerY="0.7"
|
||||
/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:startColor="#000000"
|
||||
android:centerColor="#00000000"
|
||||
android:endColor="#00000000"
|
||||
android:centerY="0.7"
|
||||
/>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
138
app/src/main/res/layout/fragment_player_tv.xml
Normal file
138
app/src/main/res/layout/fragment_player_tv.xml
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:keepScreenOn="true"
|
||||
android:id="@+id/player_background"
|
||||
app:backgroundTint="@android:color/black"
|
||||
android:background="@android:color/black"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
app:surface_type="texture_view"
|
||||
>
|
||||
<!--
|
||||
app:fastforward_increment="10000"
|
||||
app:rewind_increment="10000"-->
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
app:show_timeout="0"
|
||||
app:hide_on_touch="false"
|
||||
app:auto_show="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:controller_layout_id="@layout/player_custom_layout_tv"
|
||||
/>
|
||||
|
||||
<FrameLayout
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/player_loading_overlay"
|
||||
android:background="@android:color/black"
|
||||
android:backgroundTint="@android:color/black"
|
||||
>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="70dp"
|
||||
android:layout_gravity="center"
|
||||
app:cornerRadius="4dp"
|
||||
android:id="@+id/overlay_loading_skip_button"
|
||||
android:text="@string/skip_loading"
|
||||
|
||||
app:rippleColor="?attr/colorPrimary"
|
||||
android:textColor="?attr/textColor"
|
||||
app:iconTint="?attr/textColor"
|
||||
android:textAllCaps="false"
|
||||
app:icon="@drawable/ic_baseline_skip_next_24"
|
||||
android:backgroundTint="@color/transparent"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="45dp">
|
||||
</com.google.android.material.button.MaterialButton>
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="center"
|
||||
android:id="@+id/main_load"
|
||||
>
|
||||
</ProgressBar>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/video_go_back_holder_holder"
|
||||
android:layout_margin="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_baseline_arrow_back_24"
|
||||
app:tint="@android:color/white"
|
||||
>
|
||||
</ImageView>
|
||||
<ImageView
|
||||
android:id="@+id/player_loading_go_back"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="center"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="@drawable/video_tap_button_always_white">
|
||||
</ImageView>
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:visibility="gone"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:id="@+id/player_torrent_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:gravity="start"
|
||||
android:layout_marginTop="15dp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/white"
|
||||
android:id="@+id/video_torrent_progress"
|
||||
tools:text="78% at 18kb/s"
|
||||
>
|
||||
</TextView>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:gravity="start"
|
||||
android:layout_marginTop="0dp"
|
||||
android:textColor="@color/white"
|
||||
android:id="@+id/video_torrent_seeders"
|
||||
tools:text="17 seeders"
|
||||
app:layout_constraintTop_toBottomOf="@+id/player_video_title">
|
||||
</TextView>
|
||||
</FrameLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
373
app/src/main/res/layout/player_custom_layout_tv.xml
Normal file
373
app/src/main/res/layout/player_custom_layout_tv.xml
Normal file
|
@ -0,0 +1,373 @@
|
|||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/player_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:screenOrientation="landscape"
|
||||
tools:orientation="vertical"
|
||||
android:tag="television">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/subtitle_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<View
|
||||
android:id="@+id/shadow_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/player_gradient_tv" />
|
||||
</FrameLayout>
|
||||
<!--
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:id="@+id/video_lock_holder"
|
||||
>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_margin="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UselessParent">
|
||||
<ImageView
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_margin="20dp"
|
||||
android:id="@+id/video_locked_img"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:src="@drawable/video_locked">
|
||||
</ImageView>
|
||||
<ImageView
|
||||
android:id="@+id/video_lock"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:background="@drawable/video_tap_button_always_white">
|
||||
</ImageView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/player_video_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/player_top_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_video_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="80dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:gravity="end"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Hello world" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_video_title_rez"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="80dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:gravity="end"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
tools:text="1920x1080" />
|
||||
|
||||
<!-- Removed as it has no use anymore-->
|
||||
<!--<androidx.mediarouter.app.MediaRouteButton
|
||||
android:id="@+id/player_media_route_button"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end"
|
||||
android:layout_margin="5dp"
|
||||
android:mediaRouteTypes="user"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/player_go_back_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_baseline_arrow_back_24"
|
||||
app:tint="@android:color/white"
|
||||
android:contentDescription="@string/go_back_img_des" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/player_go_back"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/video_tap_button_always_white"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@string/go_back_img_des"
|
||||
android:focusable="true" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!--use for thinner app:trackThickness="3dp" com.google.android.material.progressindicator.CircularProgressIndicator-->
|
||||
<ProgressBar
|
||||
android:id="@+id/player_buffering"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="4dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_prev"
|
||||
style="@style/ExoMediaButton.Previous"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_repeat_toggle"
|
||||
style="@style/ExoMediaButton"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_next"
|
||||
style="@style/ExoMediaButton.Next"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_vr"
|
||||
style="@style/ExoMediaButton.VR"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_play"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@id/exo_pause"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:tintMode="src_in"
|
||||
app:tint="?attr/colorPrimaryDark"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_player_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="64dp"
|
||||
android:layout_marginEnd="64dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/player_video_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/player_pause_play"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="@drawable/video_tap_button"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:nextFocusUp="@id/player_go_back"
|
||||
android:nextFocusDown="@id/player_lock"
|
||||
|
||||
android:src="@drawable/netflix_pause"
|
||||
app:tint="@color/player_button_tv"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@id/exo_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="end"
|
||||
android:includeFontPadding="false"
|
||||
android:minWidth="50dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="normal"
|
||||
tools:text="15:30" />
|
||||
<!--app:buffered_color="@color/videoCache"-->
|
||||
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||
android:id="@id/exo_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
app:bar_height="2dp"
|
||||
app:played_color="?attr/colorPrimary"
|
||||
app:scrubber_color="?attr/colorPrimary"
|
||||
app:scrubber_dragged_size="26dp"
|
||||
app:scrubber_enabled_size="24dp"
|
||||
app:unplayed_color="@color/videoProgress" />
|
||||
|
||||
<!-- exo_duration-->
|
||||
<TextView
|
||||
android:id="@id/exo_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:includeFontPadding="false"
|
||||
android:minWidth="50dp"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="normal"
|
||||
tools:text="23:20" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_lock"
|
||||
style="@style/VideoButtonTV"
|
||||
android:nextFocusLeft="@id/player_skip_episode"
|
||||
android:nextFocusRight="@id/player_resize_btt"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
android:text="@string/video_lock"
|
||||
app:icon="@drawable/video_locked" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/player_lock_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_resize_btt"
|
||||
style="@style/VideoButtonTV"
|
||||
android:nextFocusLeft="@id/player_lock"
|
||||
android:nextFocusRight="@id/player_speed_btt"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
android:text="@string/video_aspect_ratio_resize"
|
||||
app:icon="@drawable/ic_baseline_aspect_ratio_24" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_speed_btt"
|
||||
style="@style/VideoButtonTV"
|
||||
android:nextFocusLeft="@id/player_resize_btt"
|
||||
android:nextFocusRight="@id/player_sources_btt"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
app:icon="@drawable/ic_baseline_speed_24"
|
||||
tools:text="Speed" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_sources_btt"
|
||||
style="@style/VideoButtonTV"
|
||||
android:nextFocusLeft="@id/player_speed_btt"
|
||||
android:nextFocusRight="@id/player_skip_op"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
android:text="@string/video_source"
|
||||
app:icon="@drawable/ic_baseline_playlist_play_24" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_skip_op"
|
||||
style="@style/VideoButtonTV"
|
||||
android:nextFocusLeft="@id/player_sources_btt"
|
||||
android:nextFocusRight="@id/player_skip_episode"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
android:text="@string/video_skip_op"
|
||||
app:icon="@drawable/ic_baseline_fast_forward_24" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/player_skip_episode"
|
||||
style="@style/VideoButtonTV"
|
||||
|
||||
android:nextFocusLeft="@id/player_skip_op"
|
||||
android:nextFocusRight="@id/player_lock"
|
||||
android:nextFocusUp="@id/player_pause_play"
|
||||
android:text="@string/next_episode"
|
||||
app:icon="@drawable/ic_baseline_skip_next_24" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</FrameLayout>
|
|
@ -421,6 +421,32 @@
|
|||
<item name="android:layout_marginEnd">10dp</item>
|
||||
</style>
|
||||
|
||||
<style name="VideoButtonTV">
|
||||
<item name="android:stateListAnimator">@null</item>
|
||||
<item name="strokeColor">@color/transparent</item>
|
||||
<item name="backgroundTint">@null</item>
|
||||
<item name="android:background">@drawable/player_button_tv</item>
|
||||
<item name="rippleColor">@color/white</item>
|
||||
<item name="android:shadowColor">@color/transparent</item>
|
||||
|
||||
<item name="iconTint">@color/player_on_button_tv</item>
|
||||
<item name="textColor">@color/player_on_button_tv</item>
|
||||
<item name="android:textColor">@color/player_on_button_tv</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">25dp</item>
|
||||
<item name="iconSize">16dp</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:layout_gravity">center</item>
|
||||
<item name="android:baselineAligned">false</item>
|
||||
<item name="textAllCaps">false</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textSize">10sp</item>
|
||||
<item name="android:layout_marginStart">4dp</item>
|
||||
<item name="android:layout_marginEnd">4dp</item>
|
||||
<item name="android:insetBottom">0dp</item>
|
||||
<item name="android:insetTop">0dp</item>
|
||||
</style>
|
||||
|
||||
<!--@color/white ?attr/colorPrimary-->
|
||||
<!--CHECK ?attr/darkBackground ?attr/colorPrimary-->
|
||||
<!-- CHROMECAST -->
|
||||
|
|
Loading…
Reference in a new issue