#webview #xamarin.android #xamarin.ios
#веб-просмотр #xamarin.android #xamarin.ios
Вопрос:
У меня есть страница, на которой отображаются ListView
видеоролики, полученные из URL 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 amp;amp; _webView.EnterFullScreenCommand.CanExecute(null))
{
_webView.EnterFullScreenCommand.Execute(eventArgs.View.ToView());
}
}
private void OnExitFullscreenRequested(object sender, EventArgs eventArgs)
{
if (_webView.ExitFullScreenCommand != null amp;amp; _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, она также работает хорошо !!!. есть ли какая-нибудь помощь ?.
Комментарии:
1. Привет, вы решили эту проблему?
2. Мне очень жаль, но нет, это не решено
3. Я обновил ответ. Когда у вас будет время, вы можете попробовать 🙂
Ответ №1:
Проблема должна заключаться в том, что при нажатии кнопки «Назад» видео веб-просмотра также имеет статус полноэкранного режима.Итак, вам нужно выйти из полноэкранного режима при нажатии кнопки «Назад». Кнопка возврата Android может быть переопределена как показано ниже:
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();
}
Комментарии:
1. Извините, но это то, что я пытаюсь сделать, но это не работает. пожалуйста, перечитайте мой вопрос, проблема возникает, когда я открываю видео в полноэкранном режиме и возвращаюсь с помощью кнопки Android назад, не меняя статус видео хотя бы один раз (пауза для воспроизведения или наоборот), если оно было приостановлено в списке, и я открываю его в полноэкранном режиме, а затем воспроизвожу еговернитесь, это работает хорошо и так далее.
2. @LofiMAM Привет, ответ — это одна логика для решения этой проблемы. При нажатии кнопки «Назад» лучше проверить статус видео (полноэкранный режим или статус воспроизведения). Когда все будет готово к выходу, выйдите из этой страницы. Вы можете поделиться видео или образцом проекта, я проверю его.
3. Я не хочу проверять статус, я хочу безопасно вернуться
4. @LofiMAM Окей, если этот статус может привести к небезопасному возврату, тогда нужно это сделать. 🙂
5. Да, у вас есть идея? . работа этой страницы — это просмотр списка веб-просмотров, в котором отображаются видео с разных URL-адресов, и я хочу динамичный и удобный режим открытия и возврата в полноэкранном режиме, воспроизведения и приостановки видео и так далее;
Ответ №2:
просто нужно было сосредоточиться на контенте.
В классе 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