我有一个页面,显示一个ListView
的视频,从网址获得像这样的WebView
细胞:
<ListView HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="Transparent" Margin="15,0,15,15">
<controls:FullScreenEnabledWebView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Source="{Binding viewSource}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
其中controls:FullScreenEnabledWebView
是这样的自定义渲染:
public class FullScreenEnabledWebView : WebView
{
public event Action action = delegate { };
public static readonly BindableProperty EnterFullScreenCommandProperty =
BindableProperty.Create(
nameof(EnterFullScreenCommand),
typeof(ICommand),
typeof(FullScreenEnabledWebView));
public static readonly BindableProperty ExitFullScreenCommandProperty =
BindableProperty.Create(
nameof(ExitFullScreenCommand),
typeof(ICommand),
typeof(FullScreenEnabledWebView));
public ICommand EnterFullScreenCommand
{
get => (ICommand)GetValue(EnterFullScreenCommandProperty);
set => SetValue(EnterFullScreenCommandProperty, value);
}
public ICommand ExitFullScreenCommand
{
get => (ICommand)GetValue(ExitFullScreenCommandProperty);
set => SetValue(ExitFullScreenCommandProperty, value);
}
public FullScreenEnabledWebView()
{
this.EnterFullScreenCommand = new Command<View>(DefaultEnterAsync);
this.ExitFullScreenCommand = new Command(DefaultExitAsync);
}
private async void DefaultEnterAsync(View view)
{
var page = new FullScreenVideoPage()
{
Content = view,
};
page.BackButtonPressed += () => { action.Invoke(); };
await Application.Current.MainPage.Navigation.PushModalAsync(page);
}
private async void DefaultExitAsync()
{
await Application.Current.MainPage.Navigation.PopModalAsync();
}
}
和我的android代码:
[assembly: ExportRenderer(typeof(HBRS.Controls.FullScreenEnabledWebView),typeof(FullScreenEnabledWebViewRenderer))]
namespace HBRS.Droid.Renderers.Controls
{
public class FullScreenEnabledWebViewRenderer : WebViewRenderer
{
private FullScreenEnabledWebView _webView;
FullScreenEnabledWebChromeClient client;
public FullScreenEnabledWebViewRenderer(Context context) : base(context)
{
}
/// <inheritdoc/>
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
_webView = (FullScreenEnabledWebView)e.NewElement;
_webView.action += client.OnHideCustomView;
}
protected override FormsWebChromeClient GetFormsWebChromeClient()
{
client = new FullScreenEnabledWebChromeClient();
client.EnterFullscreenRequested += OnEnterFullscreenRequested;
client.ExitFullscreenRequested += OnExitFullscreenRequested;
return client;
}
private void OnEnterFullscreenRequested(
object sender,
EnterFullScreenRequestedEventArgs eventArgs)
{
if (_webView.EnterFullScreenCommand != null && _webView.EnterFullScreenCommand.CanExecute(null))
{
_webView.EnterFullScreenCommand.Execute(eventArgs.View.ToView());
}
}
private void OnExitFullscreenRequested(object sender, EventArgs eventArgs)
{
if (_webView.ExitFullScreenCommand != null && _webView.ExitFullScreenCommand.CanExecute(null))
{
_webView.ExitFullScreenCommand.Execute(null);
}
}
}
}
其中FullScreenEnabledWebChromeClient
是:
public class FullScreenEnabledWebChromeClient : FormsWebChromeClient
{
public event EventHandler<EnterFullScreenRequestedEventArgs> EnterFullscreenRequested;
public event EventHandler ExitFullscreenRequested;
public override void OnHideCustomView()
{
base.OnHideCustomView();
ExitFullscreenRequested?.Invoke(this, EventArgs.Empty);
}
public override void OnShowCustomView(View view, ICustomViewCallback callback)
{
base.OnShowCustomView(view,callback);
EnterFullscreenRequested?.Invoke(this, new EnterFullScreenRequestedEventArgs(view));
}
public override bool OnCreateWindow(WebView view, bool isDialog, bool isUserGesture, Message resultMsg)
{
return base.OnCreateWindow(view, isDialog, isUserGesture, resultMsg);
}
}
除了下面的场景外,整个过程都很好:1。列表视图显示视频。 2.打开一些视频全屏。 3.通过使用Android设备返回按钮,而不更改它打开全屏之前的视频状态。 4.WebView
将是黑色的黑屏,我不知道为什么!!!
但是当使用webview按钮关闭全屏时它工作正常,当我改变视频状态(暂停播放或反之亦然)时,至少一次然后通过使用Android设备返回按钮返回它也很好用!。有一些帮助吗?
问题应该是当你点击后退按钮时,webview视频也是全屏状态。所以你需要在点击后退按钮时退出全屏。 Android Back按钮可以覆盖如下:
public override void OnBackPressed()
{
if (Fullscreen)
{
exitFullscreen();
//if is fullscreen ,need to exit
}else
{
if (mWebView != null)
{
mWebView.onPause();
backToFrontPage();
//if a small screen, best pause webview first,then back to frontpage
}
}
base.OnBackPressed();
}
它只需要关注内容。
在FullScreenEnabledWebview类中有以下乐趣:
private async void DefaultEnterAsync(View view)
{
var page = new FullScreenVideoPage()
{
Content = view,
};
page.BackButtonPressed += () => { action.Invoke(); };
await Application.Current.MainPage.Navigation.PushModalAsync(page);
}
只需将其修改为:
private async void DefaultEnterAsync(View view)
{
var page = new FullScreenVideoPage()
{
Content = view,
};
page.BackButtonPressed += () => { action.Invoke(); };
await Application.Current.MainPage.Navigation.PushModalAsync(page);
page.Content.Focus();
}
有关更多信息,请参阅https://github.com/mhaggag/XFAndroidFullScreenWebView,并查看问题(它与相同的存储库相关):https://github.com/mhaggag/XFAndroidFullScreenWebView/issues/3