migrate player language settings to DialogFragment; update hideBars()

* player language settings is now aDialogFragment
* update hideBars() to work with any window & view combination
* update hideBars() to use WindowCompat
This commit is contained in:
Jannik 2022-04-15 13:32:16 +02:00
parent c6a00ea061
commit 35157b78f5
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
8 changed files with 87 additions and 71 deletions

View File

@ -53,9 +53,11 @@ import kotlinx.coroutines.launch
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.parser.crunchyroll.NoneEpisode import org.mosad.teapod.parser.crunchyroll.NoneEpisode
import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.activity.player.fragment.LanguageSettingsDialogFragment
import org.mosad.teapod.ui.components.EpisodesListPlayer import org.mosad.teapod.ui.components.EpisodesListPlayer
import org.mosad.teapod.ui.components.LanguageSettingsPlayer import org.mosad.teapod.util.hideBars
import org.mosad.teapod.util.* import org.mosad.teapod.util.isInPiPMode
import org.mosad.teapod.util.navToLauncherTask
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.concurrent.scheduleAtFixedRate import kotlin.concurrent.scheduleAtFixedRate
@ -486,11 +488,8 @@ class PlayerActivity : AppCompatActivity() {
} }
private fun showLanguageSettings() { private fun showLanguageSettings() {
val languageSettings = LanguageSettingsPlayer(this, model = model).apply {
onViewRemovedAction = { model.player.play() }
}
player_layout.addView(languageSettings)
pauseAndHideControls() pauseAndHideControls()
LanguageSettingsDialogFragment().show(supportFragmentManager, LanguageSettingsDialogFragment.TAG)
} }
/** /**

View File

@ -1,54 +1,75 @@
package org.mosad.teapod.ui.components package org.mosad.teapod.ui.activity.player.fragment
import android.content.Context import android.content.DialogInterface
import android.graphics.Color import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.util.AttributeSet import android.os.Bundle
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.view.children import androidx.core.view.children
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.databinding.PlayerLanguageSettingsBinding import org.mosad.teapod.databinding.PlayerLanguageSettingsBinding
import org.mosad.teapod.ui.activity.player.PlayerViewModel import org.mosad.teapod.ui.activity.player.PlayerViewModel
import org.mosad.teapod.util.hideBars
import java.util.* import java.util.*
// TODO port to DialogFragment class LanguageSettingsDialogFragment : DialogFragment() {
class LanguageSettingsPlayer @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
model: PlayerViewModel? = null
) : LinearLayout(context, attrs, defStyleAttr) {
private val binding = PlayerLanguageSettingsBinding.inflate(LayoutInflater.from(context), this, true) private lateinit var model: PlayerViewModel
var onViewRemovedAction: (() -> Unit)? = null private lateinit var binding: PlayerLanguageSettingsBinding
private var selectedLocale = model?.currentLanguage ?: Locale.ROOT private var selectedLocale = Locale.ROOT
init { companion object {
model?.let { m -> const val TAG = "LanguageSettingsDialogFragment"
m.currentPlayback.streams.adaptive_hls.keys.forEach { languageTag -> }
val locale = Locale.forLanguageTag(languageTag)
addLanguage(locale, locale == m.currentLanguage) { v -> override fun onCreate(savedInstanceState: Bundle?) {
selectedLocale = locale super.onCreate(savedInstanceState)
updateSelectedLanguage(v as TextView) setStyle(STYLE_NO_TITLE, R.style.FullScreenDialogStyle)
} model = ViewModelProvider(requireActivity())[PlayerViewModel::class.java]
selectedLocale = model.currentLanguage
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = PlayerLanguageSettingsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.currentPlayback.streams.adaptive_hls.keys.forEach { languageTag ->
val locale = Locale.forLanguageTag(languageTag)
addLanguage(locale, locale == model.currentLanguage) { v ->
selectedLocale = locale
updateSelectedLanguage(v as TextView)
} }
} }
binding.buttonCloseLanguageSettings.setOnClickListener { close() } binding.buttonCloseLanguageSettings.setOnClickListener { dismiss() }
binding.buttonCancel.setOnClickListener { close() } binding.buttonCancel.setOnClickListener { dismiss() }
binding.buttonSelect.setOnClickListener { binding.buttonSelect.setOnClickListener {
model?.setLanguage(selectedLocale) model.setLanguage(selectedLocale)
close() dismiss()
} }
// initially hide the status and navigation bar
hideBars(requireDialog().window, binding.root)
} }
private fun addLanguage(locale: Locale, isSelected: Boolean, onClick: OnClickListener) { override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
model.player.play()
}
private fun addLanguage(locale: Locale, isSelected: Boolean, onClick: View.OnClickListener) {
val text = TextView(context).apply { val text = TextView(context).apply {
height = 96 height = 96
gravity = Gravity.CENTER_VERTICAL gravity = Gravity.CENTER_VERTICAL
@ -83,12 +104,11 @@ class LanguageSettingsPlayer @JvmOverloads constructor(
setPadding(75, 0, 0, 0) setPadding(75, 0, 0, 0)
} }
} }
} }
// set selected to selected style // set selected to selected style
selected.apply { selected.apply {
setTextColor(context.resources.getColor(R.color.exo_white, context.theme)) setTextColor(context.resources.getColor(R.color.player_white, context.theme))
setTypeface(null, Typeface.BOLD) setTypeface(null, Typeface.BOLD)
setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_baseline_check_24, 0, 0, 0) setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_baseline_check_24, 0, 0, 0)
setPadding(0, 0, 0, 0) setPadding(0, 0, 0, 0)
@ -96,10 +116,4 @@ class LanguageSettingsPlayer @JvmOverloads constructor(
compoundDrawablePadding = 12 compoundDrawablePadding = 12
} }
} }
private fun close() {
(this.parent as ViewGroup).removeView(this)
onViewRemovedAction?.invoke()
}
} }

View File

@ -5,9 +5,6 @@ import android.app.ActivityManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.commit import androidx.fragment.app.commit
@ -31,28 +28,7 @@ fun FragmentActivity.showFragment(fragment: Fragment) {
* hide the status and navigation bar * hide the status and navigation bar
*/ */
fun Activity.hideBars() { fun Activity.hideBars() {
window.apply { hideBars(window, window.decorView.rootView)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
setDecorFitsSystemWindows(false)
insetsController?.apply {
hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
systemBarsBehavior = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
WindowInsetsController.BEHAVIOR_DEFAULT
} else {
@Suppress("deprecation")
WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
}
}
} else {
@Suppress("deprecation")
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
}
} }
fun Activity.isInPiPMode(): Boolean { fun Activity.isInPiPMode(): Boolean {

View File

@ -1,6 +1,11 @@
package org.mosad.teapod.util package org.mosad.teapod.util
import android.view.View
import android.view.Window
import android.widget.TextView import android.widget.TextView
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import org.mosad.teapod.parser.crunchyroll.Collection import org.mosad.teapod.parser.crunchyroll.Collection
import org.mosad.teapod.parser.crunchyroll.ContinueWatchingItem import org.mosad.teapod.parser.crunchyroll.ContinueWatchingItem
import org.mosad.teapod.parser.crunchyroll.Item import org.mosad.teapod.parser.crunchyroll.Item
@ -50,3 +55,13 @@ fun Locale.toDisplayString(fallback: String): String {
fallback fallback
} }
} }
fun hideBars(window: Window?, root: View) {
if (window != null) {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, root).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.navigationBars())
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE
}
}
}

View File

@ -24,7 +24,7 @@
android:layout_height="70dp" android:layout_height="70dp"
android:layout_gravity="center" android:layout_gravity="center"
android:indeterminate="true" android:indeterminate="true"
app:indicatorColor="@color/exo_white" app:indicatorColor="@color/player_white"
tools:visibility="visible" /> tools:visibility="visible" />
<LinearLayout <LinearLayout
@ -84,7 +84,7 @@
android:textColor="@android:color/primary_text_light" android:textColor="@android:color/primary_text_light"
android:textSize="16sp" android:textSize="16sp"
android:visibility="gone" android:visibility="gone"
app:backgroundTint="@color/exo_white" app:backgroundTint="@color/player_white"
app:iconGravity="textStart" /> app:iconGravity="textStart" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
@ -100,7 +100,7 @@
android:textColor="@android:color/primary_text_light" android:textColor="@android:color/primary_text_light"
android:textSize="16sp" android:textSize="16sp"
android:visibility="gone" android:visibility="gone"
app:backgroundTint="@color/exo_white" app:backgroundTint="@color/player_white"
app:iconGravity="textStart" /> app:iconGravity="textStart" />
</FrameLayout> </FrameLayout>

View File

@ -37,7 +37,7 @@
android:layout_marginEnd="44dp" android:layout_marginEnd="44dp"
android:text="@string/subtitles" android:text="@string/subtitles"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/exo_white" android:textColor="@color/player_white"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" /> android:textStyle="bold" />
@ -75,7 +75,7 @@
android:layout_marginEnd="7dp" android:layout_marginEnd="7dp"
android:text="@string/cancel" android:text="@string/cancel"
android:textAllCaps="false" android:textAllCaps="false"
android:textColor="@color/exo_white" android:textColor="@color/player_white"
android:textSize="16sp" android:textSize="16sp"
app:backgroundTint="@color/buttonBackgroundLight" app:backgroundTint="@color/buttonBackgroundLight"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View File

@ -26,6 +26,9 @@
<color name="buttonBackgroundDark">#ffffff</color> <color name="buttonBackgroundDark">#ffffff</color>
<color name="controlHighlightDark">#11ffffff</color> <color name="controlHighlightDark">#11ffffff</color>
<!-- player colors -->
<color name="player_white">#ffffff</color>
<color name="ic_launcher_background">#ffffff</color> <color name="ic_launcher_background">#ffffff</color>
<color name="ic_splash_background">#ffffff</color> <color name="ic_splash_background">#ffffff</color>
</resources> </resources>

View File

@ -86,4 +86,13 @@
<item name="android:popupBackground">?themeSecondary</item> <item name="android:popupBackground">?themeSecondary</item>
</style> </style>
<style name="FullScreenDialogStyle" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
</resources> </resources>