【发布时间】:2018-11-26 14:07:50
【问题描述】:
我正在尝试在 Xamarin.Forms 项目中的 Android 上显示 PDF,它工作正常,除了第一次加载时,10 次中只有一个空白页出现 9 次。
第一次调用的是这个函数,位于 Android 项目中:
public string HTMLToPDF(string html, string filename) {
//html param is a full html description of the pdf
//filename param is something like "example.pdf"
try {
var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/folder/");
var file = new Java.IO.File(dir + "/" + filename);
if (!dir.Exists())
dir.Mkdirs();
int x = 0;
while (file.Exists())
{
x++;
file = new Java.IO.File(dir + "/" + filename + "( " + x + " )");
}
if (webpage == null)
webpage = new Android.Webkit.WebView(Android.App.Application.Context);
else
webpage.RemoveAllViews();
int width = 2100;
int height = 2970;
webpage.Layout(0, 0, width, height);
webpage.LoadData(html, "text/html", "UTF-8");
webpage.SetWebViewClient(new WebViewCallBack(file.ToString()));
this.Print(webpage, file.ToString(), filename);
return file.ToString();
}
catch (Java.Lang.Exception e)
{
App._mainPage.DisplayAlert("Error", e.Message, "Ok");
}
return "";
}
这是WebViewCallBack 类的样子:
class WebViewCallBack : Android.Webkit.WebViewClient
{
string fileNameWithPath = null;
public WebViewCallBack(string path)
{
this.fileNameWithPath = path;
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
view.SetInitialScale(1);
view.Settings.LoadWithOverviewMode = true;
view.Settings.UseWideViewPort = true;
PdfDocument document = new Android.Graphics.Pdf.PdfDocument();
Android.Graphics.Pdf.PdfDocument.Page page = document.StartPage(new Android.Graphics.Pdf.PdfDocument.PageInfo.Builder(2100, 2970, 1).Create());
view.Draw(page.Canvas);
document.FinishPage(page);
Stream filestream = new MemoryStream();
Java.IO.FileOutputStream fos = new Java.IO.FileOutputStream(fileNameWithPath, false);
try
{
document.WriteTo(filestream);
fos.Write(((MemoryStream)filestream).ToArray(), 0, (int)filestream.Length);
fos.Close();
}
catch (Java.Lang.Exception e)
{
App._mainPage.DisplayAlert("Erreur", e.Message, "Ok");
}
}
}
以及最后调用的方法Print:
public void Print(Android.Webkit.WebView webView, string filename, string onlyFileName)
{
try
{
PrintAttributes.Builder builder = new PrintAttributes.Builder();
PrintAttributes.Margins margins = new PrintAttributes.Margins(0, 0, 0, 80);
builder.SetMinMargins(margins);
builder.SetMediaSize(PrintAttributes.MediaSize.IsoA4);
builder.SetColorMode(PrintColorMode.Color);
PrintAttributes attr = builder.Build();
PrintManager printManager = (PrintManager)Forms.Context.GetSystemService(Android.Content.Context.PrintService);
var printAdapter = new GenericPrintAdapter(Forms.Context, webView, filename, onlyFileName);
printAdapter.OnEnded += PrintAdapter_OnEnded;
printAdapter.OnError += PrintAdapter_OnError;
printManager.Print(filename, printAdapter, attr);
}
catch (Java.Lang.Exception e)
{
App._mainPage.DisplayAlert("Erreur", e.Message, "Ok");
}
}
当我在WebViewCallBack 类的OnPageFinished 回调的第一行设置断点时,此时我看到了两种不同的情况:
- PDF 界面已启动,但仍在加载 PDF。在这种情况下,一旦我再次点击“播放”,PDF 就会正常加载。
- PDF 已经加载,作为一个空白页。这只发生在第一次尝试加载此特定 PDF 时。
因此我想我必须找到一种方法来强制加载程序等待OnPageFinished 方法首先运行?但这似乎是错误的。
我还可以补充一点,原始 HTML 包含图像,这些图像在我提供给 HTMLToPDF 的 html 字符串中都显示为 base64 字符串。我注意到如果 HTML 中没有图像,即使在第一次尝试时 PDF 也能很好地加载,所以我认为问题可能是 PDF 在第一次尝试准备好之前加载,可能是因为图像。不过我找不到解决办法。
有人可以帮我解释一下吗?
【问题讨论】:
-
您是否尝试过在设置 WebViewClient 之后加载 HTML?
-
不幸的是,将
LoadData放在SetWebViewClient之后似乎没有任何区别。
标签: android pdf xamarin xamarin.forms