Ao desenvolver aplicações .NET MAUI que utilizam WebViews para exibir conteúdo web, a funcionalidade de reprodução de vídeo em tela cheia é frequentemente um requisito essencial. Por padrão, em Android, o WebView pode não gerenciar a transição para o modo de tela cheia para vídeos incorporados, o que pode prejudicar a experiência do usuário. Este artigo demonstra como implementar um manipulador persnoalizado e código nativo para permitir que os usuários assistam a vídeos em tela cheia diretamente no seu WebView, sem a necessidade de sair da visualização ou abrir uma nova atividade.
Configuração no Android
Para o ambiente Android, a solução envolve estender a classe WebChromeClient para gerenciar eventos de exibição de vídeo em tela cheia.
Criação de um Cleinte Chrome Personalizado para Vídeo
Crie um arquivo chamado FullscreenWebChromeClient.cs na pasta /Platforms/Android e adicione o código a seguir. Este cliente personalizado será responsável por capturar o controle da interface do usuário quando um vídeo for iniciado em tela cheia e restaurar o estado original ao sair.
using Android.App;
using Android.Content.PM;
using Android.Content.Res;
using Android.OS;
using Android.Views;
using Android.Webkit;
using Android.Widget;
using Microsoft.Maui.Handlers;
using Microsoft.Maui.Platform;
namespace AppName.Platforms // Certifique-se de que o namespace corresponda ao seu projeto
{
public class FullscreenWebChromeClient : MauiWebChromeClient
{
private readonly Activity _currentActivity;
private int _initialSystemUiFlags;
private Android.Views.View _activeVideoView;
private ICustomViewCallback _videoPlaybackCallback;
public FullscreenWebChromeClient(IWebViewHandler handler) : base(handler)
{
_currentActivity = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
}
public override void OnHideCustomView()
{
if (_currentActivity == null || _activeVideoView == null)
return;
if (_currentActivity.Window.DecorView is FrameLayout rootLayout)
{
rootLayout.RemoveView(_activeVideoView);
}
// Apenas restaura a orientação para retrato se não for um tablet,
// ou se seu aplicativo não precisar de orientação fixa em tablets.
if (!IsTablet(_currentActivity))
{
_currentActivity.RequestedOrientation = ScreenOrientation.Portrait;
}
// Restaura as SystemBars e a barra de status
if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
{
_currentActivity.Window.SetDecorFitsSystemWindows(true);
_currentActivity.Window.InsetsController?.Show(WindowInsets.Type.SystemBars());
}
else
{
_currentActivity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)_initialSystemUiFlags;
}
_videoPlaybackCallback?.OnCustomViewHidden();
_activeVideoView = null;
_videoPlaybackCallback = null;
}
public override void OnShowCustomView(Android.Views.View view, ICustomViewCallback callback)
{
if (_activeVideoView != null)
{
OnHideCustomView(); // Garante que apenas um vídeo esteja em tela cheia por vez
return;
}
if (_currentActivity == null)
return;
_videoPlaybackCallback = callback;
_activeVideoView = view;
_activeVideoView.SetBackgroundColor(Android.Graphics.Color.Black); // Cor de fundo para o vídeo
_currentActivity.RequestedOrientation = ScreenOrientation.Landscape; // Força paisagem para vídeo
if (Build.VERSION.SdkInt >= BuildVersionCodes.R)
{
_currentActivity.Window.SetDecorFitsSystemWindows(false);
_currentActivity.Window.InsetsController?.Hide(WindowInsets.Type.SystemBars());
}
else
{
_initialSystemUiFlags = (int)_currentActivity.Window.DecorView.SystemUiVisibility;
var fullscreenFlags = _initialSystemUiFlags | (int)SystemUiFlags.LayoutStable | (int)SystemUiFlags.LayoutHideNavigation |
(int)SystemUiFlags.LayoutFullscreen | (int)SystemUiFlags.HideNavigation |
(int)SystemUiFlags.Fullscreen | (int)SystemUiFlags.Immersive;
_currentActivity.Window.DecorView.SystemUiVisibility = (StatusBarVisibility)fullscreenFlags;
}
if (_currentActivity.Window.DecorView is FrameLayout rootLayout)
{
rootLayout.AddView(_activeVideoView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
}
private bool IsTablet(Activity activity)
{
return (activity.Resources.Configuration.ScreenLayout & ScreenLayout.SizeMask) >= ScreenLayout.SizeLarge;
}
}
}
Configurando o Manipulador WebView
Crie uma classe estática em seu projeto, por exemplo, WebViewFullscreenConfigurator.cs, para configurar o WebViewHandler do .NET MAUI para usar o cliente Chrome personalizado que você acabou de criar. Adicione o seguinte código:
#if ANDROID
using AppName.Platforms; // Ajuste o namespace se necessário
using Microsoft.Maui.Handlers;
#endif
namespace AppName.Handlers // Certifique-se de que o namespace corresponda ao seu projeto
{
public static class WebViewFullscreenConfigurator
{
public static void SetupFullscreenVideoSupport()
{
#if ANDROID
Microsoft.Maui.Handlers.WebViewHandler.Mapper.ModifyMapping(
nameof(Android.Webkit.WebView.WebChromeClient),
(handler, view, args) =>
{
if (handler.PlatformView != null)
{
handler.PlatformView.SetWebChromeClient(new FullscreenWebChromeClient(handler));
}
});
#endif
}
}
}
Registro da Configuração
Para ativar esses recursos, você precisa registrar o método de configuração no arquivo MauiProgram.cs do seu aplicativo. Adicione a chamada ao método dentro do método CreateMauiApp():
using AppName.Handlers; // Ajuste o namespace se necessário
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Controls.Hosting;
namespace AppName
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
// Adicione a linha para configurar o suporte a vídeo em tela cheia
WebViewFullscreenConfigurator.SetupFullscreenVideoSupport();
return builder.Build();
}
}
}