Browse Source

remove kotlin-android-extensions, use viewBinding in Player

also replace exo_progress_placeholder with exoplayer2.ui.DefaultTimeBar since the placehoder wont work with viewbinding
develop
Jannik 3 months ago
parent
commit
fc04e8e222
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
  1. 1
      app/build.gradle
  2. 125
      app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt
  3. 2
      app/src/main/res/layout/activity_player.xml
  4. 13
      app/src/main/res/layout/player_controls.xml
  5. 1
      app/src/main/res/values-de-rDE/strings.xml
  6. 1
      app/src/main/res/values/strings.xml

1
app/build.gradle

@ -1,7 +1,6 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
}

125
app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt

@ -47,10 +47,10 @@ import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ui.StyledPlayerControlView
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_player.*
import kotlinx.android.synthetic.main.player_controls.*
import kotlinx.coroutines.launch
import org.mosad.teapod.R
import org.mosad.teapod.databinding.ActivityPlayerBinding
import org.mosad.teapod.databinding.PlayerControlsBinding
import org.mosad.teapod.parser.crunchyroll.NoneEpisode
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.activity.player.fragment.EpisodeListDialogFragment
@ -65,6 +65,8 @@ import kotlin.concurrent.scheduleAtFixedRate
class PlayerActivity : AppCompatActivity() {
private val model: PlayerViewModel by viewModels()
private lateinit var playerBinding: ActivityPlayerBinding
private lateinit var controlsBinding: PlayerControlsBinding
private lateinit var controller: StyledPlayerControlView
private lateinit var gestureDetector: GestureDetectorCompat
@ -82,6 +84,11 @@ class PlayerActivity : AppCompatActivity() {
setContentView(R.layout.activity_player)
hideBars() // Initial hide the bars
playerBinding = ActivityPlayerBinding.bind(findViewById(R.id.player_root))
println(findViewById(R.id.player_controls_root))
controlsBinding = PlayerControlsBinding.bind(findViewById(R.id.player_controls_root))
model.loadMediaAsync(
intent.getStringExtra(getString(R.string.intent_season_id)) ?: "",
intent.getStringExtra(getString(R.string.intent_episode_id)) ?: ""
@ -89,7 +96,7 @@ class PlayerActivity : AppCompatActivity() {
model.currentEpisodeChangedListener.add { onMediaChanged() }
gestureDetector = GestureDetectorCompat(this, PlayerGestureListener())
controller = video_view.findViewById(R.id.exo_controller)
controller = playerBinding.videoView.findViewById(R.id.exo_controller)
controller.isAnimationEnabled = false // disable controls (time-bar) animation
initExoPlayer() // call in onCreate, exoplayer lives in view model
@ -106,7 +113,7 @@ class PlayerActivity : AppCompatActivity() {
super.onStart()
if (Util.SDK_INT > 23) {
initPlayer()
video_view?.onResume()
playerBinding.videoView.onResume()
}
}
@ -116,7 +123,7 @@ class PlayerActivity : AppCompatActivity() {
if (Util.SDK_INT <= 23) {
initPlayer()
video_view?.onResume()
playerBinding.videoView.onResume()
}
}
@ -168,7 +175,7 @@ class PlayerActivity : AppCompatActivity() {
} else {
val width = model.player.videoFormat?.width ?: 0
val height = model.player.videoFormat?.height ?: 0
val contentFrame: View = video_view.findViewById(R.id.exo_content_frame)
val contentFrame: View = playerBinding.videoView.findViewById(R.id.exo_content_frame)
val contentRect = with(contentFrame) {
val (x, y) = intArrayOf(0, 0).also(::getLocationInWindow)
Rect(x, y, x + width, y + height)
@ -192,7 +199,7 @@ class PlayerActivity : AppCompatActivity() {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
// Hide the full-screen UI (controls, etc.) while in picture-in-picture mode.
video_view.useController = !isInPictureInPictureMode
playerBinding.videoView.useController = !isInPictureInPictureMode
}
private fun initPlayer() {
@ -214,17 +221,13 @@ class PlayerActivity : AppCompatActivity() {
override fun onPlaybackStateChanged(state: Int) {
super.onPlaybackStateChanged(state)
loading.visibility = when (state) {
playerBinding.loading.visibility = when (state) {
ExoPlayer.STATE_READY -> View.GONE
ExoPlayer.STATE_BUFFERING -> View.VISIBLE
else -> View.GONE
}
exo_play_pause.visibility = when (loading.visibility) {
View.GONE -> View.VISIBLE
View.VISIBLE -> View.INVISIBLE
else -> View.VISIBLE
}
controlsBinding.exoPlayPause.isVisible = !playerBinding.loading.isVisible
if (state == ExoPlayer.STATE_ENDED && hasNextEpisode() && Preferences.autoplay) {
playNextEpisode()
@ -239,10 +242,10 @@ class PlayerActivity : AppCompatActivity() {
@SuppressLint("ClickableViewAccessibility")
private fun initVideoView() {
video_view.player = model.player
playerBinding.videoView.player = model.player
// when the player controls get hidden, hide the bars too
video_view.setControllerVisibilityListener {
playerBinding.videoView.setControllerVisibilityListener {
when (it) {
View.GONE -> {
hideBars()
@ -252,23 +255,23 @@ class PlayerActivity : AppCompatActivity() {
}
}
video_view.setOnTouchListener { _, event ->
playerBinding.videoView.setOnTouchListener { _, event ->
gestureDetector.onTouchEvent(event)
true
}
}
private fun initActions() {
exo_close_player.setOnClickListener {
controlsBinding.exoClosePlayer.setOnClickListener {
this.finish()
}
rwd_10.setOnButtonClickListener { rewind() }
ffwd_10.setOnButtonClickListener { fastForward() }
button_next_ep.setOnClickListener { playNextEpisode() }
button_skip_op.setOnClickListener { skipOpening() }
button_language.setOnClickListener { showLanguageSettings() }
button_episodes.setOnClickListener { showEpisodesList() }
button_next_ep_c.setOnClickListener { playNextEpisode() }
controlsBinding.rwd10.setOnButtonClickListener { rewind() }
controlsBinding.ffwd10.setOnButtonClickListener { fastForward() }
playerBinding.buttonNextEp.setOnClickListener { playNextEpisode() }
playerBinding.buttonSkipOp.setOnClickListener { skipOpening() }
controlsBinding.buttonLanguage.setOnClickListener { showLanguageSettings() }
controlsBinding.buttonEpisodes.setOnClickListener { showEpisodesList() }
controlsBinding.buttonNextEpC.setOnClickListener { playNextEpisode() }
}
private fun initGUI() {
@ -286,7 +289,7 @@ class PlayerActivity : AppCompatActivity() {
timerUpdates = Timer().scheduleAtFixedRate(0, 500) {
lifecycleScope.launch {
val currentPosition = model.player.currentPosition
val btnNextEpIsVisible = button_next_ep.isVisible
val btnNextEpIsVisible = playerBinding.buttonNextEp.isVisible
val controlsVisible = controller.isVisible
// make sure remaining time is > 0
@ -310,10 +313,12 @@ class PlayerActivity : AppCompatActivity() {
model.currentEpisodeMeta?.let {
if (it.openingDuration > 0 &&
currentPosition in it.openingStart..(it.openingStart + 10000) &&
!button_skip_op.isVisible
!playerBinding.buttonSkipOp.isVisible
) {
showButtonSkipOp()
} else if (button_skip_op.isVisible && currentPosition !in it.openingStart..(it.openingStart + 10000)) {
} else if (playerBinding.buttonSkipOp.isVisible &&
currentPosition !in it.openingStart..(it.openingStart + 10000)
) {
// the button should only be visible, if currentEpisodeMeta != null
hideButtonSkipOp()
}
@ -328,7 +333,7 @@ class PlayerActivity : AppCompatActivity() {
}
private fun onPauseOnStop() {
video_view?.onPause()
playerBinding.videoView.onPause()
model.player.pause()
timerUpdates.cancel()
}
@ -343,7 +348,7 @@ class PlayerActivity : AppCompatActivity() {
val seconds = TimeUnit.MILLISECONDS.toSeconds(remainingTime) % 60
// if remaining time is below 60 minutes, don't show hours
exo_remaining.text = if (TimeUnit.MILLISECONDS.toMinutes(remainingTime) < 60) {
controlsBinding.exoRemaining.text = if (TimeUnit.MILLISECONDS.toMinutes(remainingTime) < 60) {
getString(R.string.time_min_sec, minutes, seconds)
} else {
getString(R.string.time_hour_min_sec, hours, minutes, seconds)
@ -361,10 +366,10 @@ class PlayerActivity : AppCompatActivity() {
this.finish()
}
exo_text_title.text = model.getMediaTitle()
controlsBinding.exoTextTitle.text = model.getMediaTitle()
// hide the next episode button, if there is none
button_next_ep_c.visibility = if (hasNextEpisode()) View.VISIBLE else View.GONE
controlsBinding.buttonNextEpC.isVisible = hasNextEpisode()
}
/**
@ -384,36 +389,36 @@ class PlayerActivity : AppCompatActivity() {
model.seekToOffset(rwdTime)
// hide/show needed components
exo_double_tap_indicator.visibility = View.VISIBLE
ffwd_10_indicator.visibility = View.INVISIBLE
rwd_10.visibility = View.INVISIBLE
rwd_10_indicator.onAnimationEndCallback = {
exo_double_tap_indicator.visibility = View.GONE
ffwd_10_indicator.visibility = View.VISIBLE
rwd_10.visibility = View.VISIBLE
playerBinding.exoDoubleTapIndicator.visibility = View.VISIBLE
playerBinding.ffwd10Indicator.visibility = View.INVISIBLE
controlsBinding.rwd10.visibility = View.INVISIBLE
playerBinding.rwd10Indicator.onAnimationEndCallback = {
playerBinding.exoDoubleTapIndicator.visibility = View.GONE
playerBinding.ffwd10Indicator.visibility = View.VISIBLE
controlsBinding.rwd10.visibility = View.VISIBLE
}
// run animation
rwd_10_indicator.runOnClickAnimation()
playerBinding.rwd10Indicator.runOnClickAnimation()
}
private fun fastForward() {
model.seekToOffset(fwdTime)
// hide/show needed components
exo_double_tap_indicator.visibility = View.VISIBLE
rwd_10_indicator.visibility = View.INVISIBLE
ffwd_10.visibility = View.INVISIBLE
ffwd_10_indicator.onAnimationEndCallback = {
exo_double_tap_indicator.visibility = View.GONE
rwd_10_indicator.visibility = View.VISIBLE
ffwd_10.visibility = View.VISIBLE
playerBinding.exoDoubleTapIndicator.visibility = View.VISIBLE
playerBinding.rwd10Indicator.visibility = View.INVISIBLE
controlsBinding.ffwd10.visibility = View.INVISIBLE
playerBinding.ffwd10Indicator.onAnimationEndCallback = {
playerBinding.exoDoubleTapIndicator.visibility = View.GONE
playerBinding.rwd10Indicator.visibility = View.VISIBLE
controlsBinding.ffwd10.visibility = View.VISIBLE
}
// run animation
ffwd_10_indicator.runOnClickAnimation()
playerBinding.ffwd10Indicator.runOnClickAnimation()
}
private fun playNextEpisode() {
@ -434,10 +439,10 @@ class PlayerActivity : AppCompatActivity() {
* TODO improve the show animation
*/
private fun showButtonNextEp() {
button_next_ep.isVisible = true
button_next_ep.alpha = 0.0f
playerBinding.buttonNextEp.isVisible = true
playerBinding.buttonNextEp.alpha = 0.0f
button_next_ep.animate()
playerBinding.buttonNextEp.animate()
.alpha(1.0f)
.setListener(null)
}
@ -447,33 +452,33 @@ class PlayerActivity : AppCompatActivity() {
* TODO improve the hide animation
*/
private fun hideButtonNextEp() {
button_next_ep.animate()
playerBinding.buttonNextEp.animate()
.alpha(0.0f)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
button_next_ep.isVisible = false
playerBinding.buttonNextEp.isVisible = false
}
})
}
private fun showButtonSkipOp() {
button_skip_op.isVisible = true
button_skip_op.alpha = 0.0f
playerBinding.buttonSkipOp.isVisible = true
playerBinding.buttonSkipOp.alpha = 0.0f
button_skip_op.animate()
playerBinding.buttonSkipOp.animate()
.alpha(1.0f)
.setListener(null)
}
private fun hideButtonSkipOp() {
button_skip_op.animate()
playerBinding.buttonSkipOp.animate()
.alpha(0.0f)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
button_skip_op.isVisible = false
playerBinding.buttonSkipOp.isVisible = false
}
})
@ -516,7 +521,7 @@ class PlayerActivity : AppCompatActivity() {
*/
override fun onDoubleTap(e: MotionEvent?): Boolean {
val eventPosX = e?.x?.toInt() ?: 0
val viewCenterX = video_view.measuredWidth / 2
val viewCenterX = playerBinding.videoView.measuredWidth / 2
// if the event position is on the left side rewind, if it's on the right forward
if (eventPosX < viewCenterX) rewind() else fastForward()

2
app/src/main/res/layout/activity_player.xml

@ -2,7 +2,7 @@
<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_layout"
android:id="@+id/player_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"

13
app/src/main/res/layout/player_controls.xml

@ -2,6 +2,7 @@
<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_controls_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#73000000">
@ -94,11 +95,12 @@
android:layout_marginEnd="12dp"
android:layout_marginBottom="@dimen/player_styled_progress_margin_bottom">
<View
android:id="@+id/exo_progress_placeholder"
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_height="@dimen/player_styled_progress_layout_height"
android:layout_marginBottom="2dp"
android:contentDescription="@string/desc_time_bar"
app:bar_height="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/exo_remaining"
app:layout_constraintStart_toStartOf="parent"
@ -107,9 +109,10 @@
<TextView
android:id="@+id/exo_remaining"
style="@style/ExoStyledControls.TimeText.Position"
android:layout_height="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout

1
app/src/main/res/values-de-rDE/strings.xml

@ -84,6 +84,7 @@
<string name="episodes">Folgen</string>
<string name="episode">Folge</string>
<string name="no_subtitles">Aus</string>
<string name="desc_time_bar">Zeitleiste</string>
<!-- Onboarding -->
<string name="skip">Überspringen</string>

1
app/src/main/res/values/strings.xml

@ -106,6 +106,7 @@
<string name="episodes">Episodes</string>
<string name="episode">Episode</string>
<string name="no_subtitles">None</string>
<string name="desc_time_bar">time bar</string>
<!-- Onboarding -->
<string name="skip">Skip</string>

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close