Reputation: 129
I have a sample pdf URL "http://www.africau.edu/images/default/sample.pdf". I want to show this pdf file and display in my mobile app using Xamarin.Forms. I tried using webviews and some custom renderers but did not work.
public class PdfViewRenderer : WebViewRenderer
{
internal class PdfWebChromeClient : WebChromeClient
{
public override bool OnJsAlert(Android.Webkit.WebView view, string url, string message, JsResult result)
{
if (message != "PdfViewer_app_scheme:print")
{
return base.OnJsAlert(view, url, message, result);
}
using (var printManager = Forms.Context.GetSystemService(Android.Content.Context.PrintService) as PrintManager)
{
printManager?.Print(FileName, new FilePrintDocumentAdapter(FileName, Uri), null);
}
return true;
}
public string Uri { private get; set; }
public string FileName { private get; set; }
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
{
return;
}
var pdfView = Element as PdfView;
if (pdfView == null)
{
return;
}
if (string.IsNullOrWhiteSpace(pdfView.Uri) == false)
{
Control.SetWebChromeClient(new PdfWebChromeClient
{
Uri = pdfView.Uri,
//FileName = GetFileNameFromUri(pdfView.Uri)
});
}
Control.Settings.AllowFileAccess = true;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
LoadFile(pdfView.Uri);
}
private static string GetFileNameFromUri(string uri)
{
var lastIndexOf = uri?.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase);
return lastIndexOf > 0 ? uri.Substring(lastIndexOf.Value, uri.Length - lastIndexOf.Value) : string.Empty;
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName != PdfView.UriProperty.PropertyName)
{
return;
}
var pdfView = Element as PdfView;
if (pdfView == null)
{
return;
}
if (string.IsNullOrWhiteSpace(pdfView.Uri) == false)
{
Control.SetWebChromeClient(new PdfWebChromeClient
{
Uri = pdfView.Uri,
// FileName = GetFileNameFromUri(pdfView.Uri)
});
}
LoadFile(pdfView.Uri);
}
private void LoadFile(string uri)
{
if (string.IsNullOrWhiteSpace(uri))
{
return;
}
//Control.Resources = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", string.Format("ms-appx-web:///Assets/Content/{0}", WebUtility.UrlEncode(PdfView.Uri))));
Control.LoadUrl($"file:///android_asset/pdfjs/web/viewer.html?file=file://{uri}");
//Control.LoadUrl(uri);
Control.LoadUrl(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", string.Format("ms-appx-web:///Assets/Content/{0}", WebUtility.UrlEncode(uri))));
}
}
Upvotes: 1
Views: 3604
Reputation: 421
In Android
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace DipsDemoXaml.Droid.Renderer
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.Settings.BuiltInZoomControls = true;
Control.Settings.DisplayZoomControls = true;
}
this.Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "Uri") return;
var customWebView = Element as CustomWebView;
if (customWebView != null)
{
Control.LoadUrl(string.Format("file:///android_asset/pdfjs/web/viewer.html?file={0}", string.Format("file:///android_asset/Content/{0}", WebUtility.UrlEncode(customWebView.Uri))));
}
}
}
}
for iOS
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace DipsDemoXaml.iOS.Renderes
{
public class CustomWebViewRenderer : ViewRenderer<CustomWebView, UIWebView>
{
protected override void OnElementChanged(ElementChangedEventArgs<CustomWebView>
e)
{
base.OnElementChanged(e);
if (Control == null)
{
SetNativeControl(new UIWebView());
}
if (e.OldElement != null)
{
// Cleanup
}
if (e.NewElement != null)
{
var customWebView = Element as CustomWebView;
string fileName = Path.Combine(NSBundle.MainBundle.BundlePath, string.Format("Content/{0}", WebUtility.UrlEncode(customWebView.Uri)));
Control.LoadRequest(new NSUrlRequest(new NSUrl(fileName, false)));
Control.ScalesPageToFit = true;
}
this.Opaque = false;
this.BackgroundColor = Color.Transparent.ToUIColor();
}
}
}
In shared
namespace DipsDemoXaml.Custom.Renderer
{
public class CustomWebView : WebView
{
public static readonly BindableProperty UriProperty =
BindableProperty.Create(nameof(Uri),typeof(string),
typeof(CustomWebView),default(string))
;
public string Uri
{
get => (string) GetValue(UriProperty);
set => SetValue(UriProperty, value);
}
}
}
In XAML You can Call Like this
<renderer:CustomWebView Uri="{Binding SelectedJournal.Uri}" />
I think Problem in your Custom Rendering You can Create a new property like URI in a string and You can Call the URI you need a way to access Android and iOS webview for that you can call android asset pdf viewer for android and for Ios you can pass a new NSUrl to load the pdf inside your app
Upvotes: 1
Reputation: 1959
Your XAML
<WebView x:Name="Webview"
HeightRequest="1000"
WidthRequest="1000"
VerticalOptions="FillAndExpand"/>
Put your Webview source like this
Webview.Source = "https://docs.google.com/gview?
embedded=true&url="+"http://www.africau.edu/images/default/sample.pdf";
Upvotes: 2