как решить мою проблему с возвратом с полноэкранной страницы веб-видео

#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