diff --git a/core-sample-app/src/main/AndroidManifest.xml b/core-sample-app/src/main/AndroidManifest.xml
index f21c670f..c0e1f76b 100644
--- a/core-sample-app/src/main/AndroidManifest.xml
+++ b/core-sample-app/src/main/AndroidManifest.xml
@@ -85,6 +85,11 @@
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
android:hardwareAccelerated="true"
android:label="@string/simple_example" />
+
exitFullScreen) {
+ // the video will continue playing in fullScreenView
+ youTubePlayerView.setVisibility(View.GONE);
+ fullScreenViewContainer.setVisibility(View.VISIBLE);
+ fullScreenViewContainer.addView(fullScreenView);
+
+ // optionally request landscape orientation
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
+
+ @Override
+ public void onExitFullScreen() {
+ // the video will continue playing in the player
+ youTubePlayerView.setVisibility(View.VISIBLE);
+ fullScreenViewContainer.setVisibility(View.GONE);
+ fullScreenViewContainer.removeAllViews();
+
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+ }
+ });
+
+ youTubePlayerView.initialize(new AbstractYouTubePlayerListener() {
+ @Override
+ public void onReady(@NonNull YouTubePlayer youTubePlayer) {
+ super.onReady(youTubePlayer);
+ youTubePlayer.loadVideo("S0Q4gqBUs7c", 0F);
+ }
+ }, iFramePlayerOptions);
+
+ getLifecycle().addObserver(youTubePlayerView);
+ }
+}
diff --git a/core-sample-app/src/main/res/layout/activity_fullscreen_example.xml b/core-sample-app/src/main/res/layout/activity_fullscreen_example.xml
new file mode 100644
index 00000000..3f799e5b
--- /dev/null
+++ b/core-sample-app/src/main/res/layout/activity_fullscreen_example.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-sample-app/src/main/res/values/strings.xml b/core-sample-app/src/main/res/values/strings.xml
index 3ebc216b..249433fe 100644
--- a/core-sample-app/src/main/res/values/strings.xml
+++ b/core-sample-app/src/main/res/values/strings.xml
@@ -1,6 +1,7 @@
ayp API
Simple example
+ Fullscreen example
Complete example
RecyclerView example
Custom UI example
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt
index 6f6624db..6bd9daaa 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/AbstractYouTubePlayerListener.kt
@@ -1,5 +1,7 @@
package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners
+import android.view.View
+import android.webkit.WebChromeClient
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt
new file mode 100644
index 00000000..6b75b7de
--- /dev/null
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/FullScreenListener.kt
@@ -0,0 +1,31 @@
+package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners
+
+import android.view.View
+
+/**
+ * Interface used to keep track of full screen events
+ */
+interface FullScreenListener {
+ /**
+ * Notify the host application that the player has entered full screen mode
+ * (the full screen button in the player UI has been clicked).
+ * After this call, the video will no longer be rendered in the [YouTubePlayerView],
+ * but will instead be rendered in [fullScreenView].
+ * The host application should add this View to a container that fills the screen
+ * in order to actually display the video full screen.
+ *
+ * The application can explicitly exit fullscreen mode by invoking [exitFullScreen]
+ * (for example when the user presses the back button).
+ * However, the player will show its own UI to exist fullscreen.
+ * Regardless of how the player exits fullscreen mode, [onEnterFullScreen] will be invoked,
+ * signaling for the application to remove the custom View.
+ */
+ fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit)
+
+ /**
+ * Notify the host application that the player has exited full screen mode.
+ * The host application must hide the custom View (the View which was previously passed to
+ * [onEnterFullScreen]). After this call, the video will render in the player again.
+ */
+ fun onExitFullScreen()
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt
index 1fdd7eb0..0ed37f2b 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/listeners/YouTubePlayerListener.kt
@@ -1,5 +1,7 @@
package com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners
+import android.view.View
+import android.webkit.WebChromeClient
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt
index a4ee1b05..e948e9f7 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/options/IFramePlayerOptions.kt
@@ -161,6 +161,16 @@ class IFramePlayerOptions private constructor(private val playerOptions: JSONObj
return this
}
+ /**
+ * Setting this parameter to 0 prevents the fullscreen button from displaying in the player.
+ * See original documentation for more info: https://developers.google.com/youtube/player_parameters#Parameters
+ * @param fs if set to 1: the player fullscreen button will be show. If set to 0: the player fullscreen button will not be shown.
+ */
+ fun fullscreen(fs: Int): Builder {
+ addInt(FS, fs)
+ return this
+ }
+
private fun addString(key: String, value: String) {
try {
builderOptions.put(key, value)
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt
index a2f05729..065cdb8e 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/LegacyYouTubePlayerView.kt
@@ -13,6 +13,7 @@ import androidx.lifecycle.OnLifecycleEvent
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener
+import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.FullScreenListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerCallback
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions
@@ -23,13 +24,16 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.Playbac
* Legacy internal implementation of YouTubePlayerView. The user facing YouTubePlayerView delegates
* most of its actions to this one.
*/
-internal class LegacyYouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0):
- SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver {
+internal class LegacyYouTubePlayerView(
+ context: Context,
+ listener: FullScreenListener,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+): SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver {
- constructor(context: Context): this(context, null, 0)
- constructor(context: Context, attrs: AttributeSet? = null): this(context, attrs, 0)
+ constructor(context: Context): this(context, FakeWebViewYouTubeListener,null, 0)
- internal val youTubePlayer: WebViewYouTubePlayer = WebViewYouTubePlayer(context)
+ internal val youTubePlayer: WebViewYouTubePlayer = WebViewYouTubePlayer(context, listener)
private val networkListener = NetworkListener()
private val playbackResumer = PlaybackResumer()
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt
index 205b9d25..a2d683a2 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/WebViewYouTubePlayer.kt
@@ -14,17 +14,33 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.R
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayerBridge
+import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.FullScreenListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.toFloat
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.Utils
import java.util.*
+
+internal object FakeWebViewYouTubeListener : FullScreenListener {
+ override fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit) { }
+ override fun onExitFullScreen() { }
+}
+
/**
* WebView implementation of [YouTubePlayer]. The player runs inside the WebView, using the IFrame Player API.
*/
-internal class WebViewYouTubePlayer constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
- : WebView(context, attrs, defStyleAttr), YouTubePlayer, YouTubePlayerBridge.YouTubePlayerBridgeCallbacks {
+internal class WebViewYouTubePlayer constructor(
+ context: Context,
+ private val listener: FullScreenListener,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : WebView(context, attrs, defStyleAttr),
+ YouTubePlayer,
+ YouTubePlayerBridge.YouTubePlayerBridgeCallbacks {
+
+ /** Constructor used by tools */
+ constructor(context: Context) : this(context, FakeWebViewYouTubeListener)
private lateinit var youTubePlayerInitListener: (YouTubePlayer) -> Unit
@@ -114,6 +130,17 @@ internal class WebViewYouTubePlayer constructor(context: Context, attrs: Attribu
// if the video's thumbnail is not in memory, show a black screen
webChromeClient = object : WebChromeClient() {
+
+ override fun onShowCustomView(view: View, callback: CustomViewCallback) {
+ super.onShowCustomView(view, callback)
+ listener.onEnterFullScreen(view) { callback.onCustomViewHidden() }
+ }
+
+ override fun onHideCustomView() {
+ super.onHideCustomView()
+ listener.onExitFullScreen()
+ }
+
override fun getDefaultVideoPoster(): Bitmap? {
val result = super.getDefaultVideoPoster()
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt
index 3f66919d..468cd07c 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/player/views/YouTubePlayerView.kt
@@ -4,6 +4,8 @@ import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams
+import android.widget.FrameLayout
import androidx.annotation.LayoutRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
@@ -13,22 +15,50 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerCallback
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener
+import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.*
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.options.IFramePlayerOptions
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo
-class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0):
- SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver {
+private val matchParent get() = FrameLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT
+)
+
+class YouTubePlayerView(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : SixteenByNineFrameLayout(context, attrs, defStyleAttr), LifecycleObserver {
constructor(context: Context): this(context, null, 0)
constructor(context: Context, attrs: AttributeSet? = null): this(context, attrs, 0)
- private val legacyTubePlayerView: LegacyYouTubePlayerView = LegacyYouTubePlayerView(context)
+ private val fullScreenListeners = mutableListOf()
+
+ /**
+ * A single [FullScreenListener] that is always added to the WebView,
+ * responsible for calling all optional listeners added from clients of the library.
+ */
+ private val webViewFullScreenListener = object : FullScreenListener {
+ override fun onEnterFullScreen(fullScreenView: View, exitFullScreen: () -> Unit) {
+ fullScreenListeners.forEach { it.onEnterFullScreen(fullScreenView, exitFullScreen) }
+ }
+
+ override fun onExitFullScreen() {
+ fullScreenListeners.forEach { it.onExitFullScreen() }
+ }
+ }
+
+ private val legacyTubePlayerView = LegacyYouTubePlayerView(
+ context,
+ webViewFullScreenListener
+ )
// this is a publicly accessible API
var enableAutomaticInitialization: Boolean
init {
- addView(legacyTubePlayerView, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
+ addView(legacyTubePlayerView, matchParent)
val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.YouTubePlayerView, 0, 0)
@@ -145,6 +175,10 @@ class YouTubePlayerView(context: Context, attrs: AttributeSet? = null, defStyleA
fun removeYouTubePlayerListener(youTubePlayerListener: YouTubePlayerListener) = legacyTubePlayerView.youTubePlayer.removeListener(youTubePlayerListener)
+ fun addFullScreenListener(fullScreenListener: FullScreenListener) = fullScreenListeners.add(fullScreenListener)
+
+ fun removeFullScreenListener(fullScreenListener: FullScreenListener) = fullScreenListeners.remove(fullScreenListener)
+
/**
* Convenience method to set the [YouTubePlayerView] width and height to match parent.
*/
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt
index 943c6c28..af98bbc5 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/utils/FadeViewHelper.kt
@@ -2,6 +2,7 @@ package com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.utils
import android.animation.Animator
import android.view.View
+import android.webkit.WebChromeClient
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener
diff --git a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt
index 12362607..1ad56bea 100644
--- a/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt
+++ b/core/src/main/java/com/pierfrancescosoffritti/androidyoutubeplayer/core/ui/views/YouTubePlayerSeekBar.kt
@@ -4,6 +4,8 @@ import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
+import android.view.View
+import android.webkit.WebChromeClient
import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.TextView