In a Forms app we use a custom WebViewRenderer
in the .Droid
project to display html that contains videos embedded in <iframe>
.
I'm having trouble making these videos go into full screen when the user pushes the button to toggle full screen in the video player.
I'm trying to use WebChromeClient
, as per Xamarin's WebView full screen advise to toggle full screen mode. However, I'm not sure how to go about this. I have tried to port a Java implementation of WebChromeClient but I just get a blank screen after OnShowCustomView(View view, ICustomViewCallback callback)
has finished executing.
Here's the code (I think is relevant), let me know if I'm missing important pieces.
CustomRenderer for WebView:
public class MyWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
var activity = this.Context as Activity;
var view = activity.LayoutInflater.Inflate(Resource.Layout.fullScreenVideoLayouts, this, false);
ViewGroup videoViewLayout = (ViewGroup) view.FindViewById(Resource.Id.videoLayout);
View nonVideoLayout = view.FindViewById(Resource.Id.nonVideoLayout);
control.SetWebChromeClient( new WebViewWebChromeClient(nonVideoLayout, videoViewLayout));
}
}
Custom VideoEnabledWebChromeClient:
private class WebViewWebChromeClient : WebChromeClient
{
private View _activityNonVideoView;
private ViewGroup _activityVideoView;
private bool _isVideoFullscreen; // Indicates if the video is being displayed using a custom view (typically full-screen)
private FrameLayout _videoViewContainer;
private ICustomViewCallback _videoViewCallback;
public WebViewWebChromeClient() { }
public WebViewWebChromeClient(View view, ViewGroup formsViewGroup)
{
this._activityNonVideoView = view;
this._activityVideoView = formsViewGroup;
}
public override void OnShowCustomView(View view, ICustomViewCallback callback)
{
base.OnShowCustomView(view, callback);
FrameLayout frameLayout = view as FrameLayout;
_isVideoFullscreen = true;
_videoViewContainer = frameLayout;
_videoViewCallback = callback;
// Hide the non-video view, add the video view, and show it
_activityNonVideoView.Visibility = ViewStates.Invisible;
_activityVideoView.AddView(_videoViewContainer, new ViewGroup.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent));
_activityVideoView.Visibility = ViewStates.Visible;
}
public override void OnHideCustomView()
{
base.OnHideCustomView();
if (_isVideoFullscreen)
{
// Hide the video view, remove it, and show the non-video view
_activityVideoView.Visibility = ViewStates.Invisible;
_activityVideoView.RemoveView(_videoViewContainer);
_activityNonVideoView.Visibility = ViewStates.Visible;
if (_videoViewCallback != null)
{
_videoViewCallback.OnCustomViewHidden();
}
_isVideoFullscreen = false;
_videoViewContainer = null;
_videoViewCallback = null;
}
}
}
Inflated .axml file (ported from original):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- View that will be hidden when video goes fullscreen -->
<RelativeLayout
android:id="@+id/nonVideoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/> >
</RelativeLayout>
I am very new to Xamarin and Android development so I might be going about this all wrong. Please let me know if there are other ways of handling this much easier. I'm forced to use this setup with WebView and videos in iframe's but other things I'm not aware of might be possible to change. Any help is much appreciated.