I have a Custom Renderer to enable download and zoom options when a WebView is opened in Xamarin, but even seeting the Source with a URL parameter, the page shows empty screen. What to do?
My WebView.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:loading="clr-namespace:MPS.Libertas.Mobile.Styles.Frames"
xmlns:behaviors="clr-namespace:MPS.Libertas.Mobile.Behaviors"
x:Class="MPS.Libertas.Mobile.Views.DetalhesDoProcesso.PecasPJe"
Title="{Binding Title}">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="#E6E8EA" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<WebView x:Name="wvPecasPJe" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
Navigated="PagOnNavigated"
Navigating="PagOnNavigating"
Source="{Binding Value, Mode=TwoWay}"
/>
</StackLayout>
</ContentPage>
And code setting the Source value behind:
private UrlWebViewSource _Value;
public UrlWebViewSource Value
{
get { return _Value; }
set
{
if (_Value != value)
{
_Value = value;
OnPropertyChanged(new PropertyChangedEventArgs("Value"));
}
}
}
public override async Task InitializeAsync(object navigationData)
{
IsRefreshing = true;
try
{
if (navigationData is string linkPecasPJe)
{
Value = new UrlWebViewSource
{
Url = $"{linkPecasPJe}"
};
Console.WriteLine(Value);
}
else
{
throw new InvalidOperationException("Não foi possível recuperar o link das peças.");
}
}
catch (Exception ex)
{
await DialogService.ShowError(ex, "Erro ao abrir as peças do PJe!", "Voltar", null);
await NavigationService.NavigateToPrevious();
}
finally
{
IsRefreshing = false;
await base.InitializeAsync(navigationData);
}
}
My CustomRenderer:
using Android.App;
using Android.Webkit;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using Android.Content;
using Xamarin.Essentials;
using System.IO;
using System;
using MPS.Libertas.Mobile.Droid.Renderers;
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyWebView))]
namespace MPS.Libertas.Mobile.Droid.Renderers
{
internal class MyWebView : WebViewRenderer
{
public MyWebView(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (this.Control != null)
{
var webView = new global::Android.Webkit.WebView(this.Context);
webView.SetWebViewClient(new WebViewClient());
webView.SetWebChromeClient(new WebChromeClient());
WebSettings webSettings = webView.Settings;
webSettings.JavaScriptEnabled = true;
webView.SetDownloadListener(new CustomDownloadListener());
this.SetNativeControl(webView);
var source = e.NewElement.Source as UrlWebViewSource;
if (source != null)
{
webView.LoadUrl(source.Url);
}
}
}
}
public class CustomDownloadListener : Java.Lang.Object, IDownloadListener
{
public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
{
try
{
DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
request.AllowScanningByMediaScanner();
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
// if this path is not create, we can create it.
string thmblibrary = FileSystem.AppDataDirectory + "/download";
if (!Directory.Exists(thmblibrary))
Directory.CreateDirectory(thmblibrary);
request.SetDestinationInExternalFilesDir(Android.App.Application.Context, FileSystem.AppDataDirectory, "download");
DownloadManager dm = (DownloadManager)Android.App.Application.Context.GetSystemService(Android.App.Application.DownloadService);
dm.Enqueue(request);
}
catch (Exception)
{
throw;
}
}
}
}
I noticed that, in the CustomRenderer, the source keeps loading with a null value. But the page should load even then because I am setting the source in the ViewModel, shouldnt it?