フォームから印刷ダイアログを使用する必要があります。私はiOSのソリューションを見つけましたが、アンドロイドの実装は私に問題をもたらしています。Xamarin.Forms経由でAndroidにローカルファイルを印刷する
私が見る限り、Androidのプリントマネージャを呼び出してファイルを解析することはできません。 AndroidView.Viewのみ表示できますが、それは本当ですか? これは私の理想的な解決策です。
私は自分のコンテンツ(ローカルPDFを表示しているwebview)をこのアンドロイドビューに変換しようとしましたが、これも実際には機能していないようですが、ここで私の奥行きを外しています。
以下のコードでは、forms.webviewをandroid.viewに変換し、それを印刷マネージャーに解析してみます。 これは印刷ダイアログを生成しますが、黒い白いページです。
var size = new Rectangle(webview.X, webview.Y, webview.Width, webview.Height);
var vRenderer = Xamarin.Forms.Platform.Android.Platform.CreateRenderer(webview);
var viewGroup = vRenderer.ViewGroup;
vRenderer.Tracker.UpdateLayout();
var layoutParams = new Android.Views.ViewGroup.LayoutParams((int)size.Width, (int)size.Height);
viewGroup.LayoutParameters = layoutParams;
webview.Layout(size);
viewGroup.Layout(0, 0, (int)webview.WidthRequest, (int)webview.HeightRequest);
var printMgr = (Android.Print.PrintManager)Forms.Context.GetSystemService(Android.Content.Context.PrintService);
var docAdt = new Droid.GenericPrintAdapter(Forms.Context, viewGroup);
printMgr.Print("test", docAdt, null);
次は、私は今、 "ワーキング" のソリューションを持っている "GenericPrintAdapter"
public class GenericPrintAdapter : PrintDocumentAdapter
{
View view;
Context context;
PrintedPdfDocument document;
float scale;
public GenericPrintAdapter(Context context, View view)
{
this.view = view;
this.context = context;
}
public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras)
{
document = new PrintedPdfDocument(context, newAttributes);
CalculateScale(newAttributes);
var printInfo = new PrintDocumentInfo
.Builder("MyPrint.pdf")
.SetContentType(PrintContentType.Document)
.SetPageCount(1)
.Build();
callback.OnLayoutFinished(printInfo, true);
}
void CalculateScale(PrintAttributes newAttributes)
{
int dpi = Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi);
int leftMargin = (int)(dpi * (float)newAttributes.MinMargins.LeftMils/1000);
int rightMargin = (int)(dpi * (float)newAttributes.MinMargins.RightMils/1000);
int topMargin = (int)(dpi * (float)newAttributes.MinMargins.TopMils/1000);
int bottomMargin = (int)(dpi * (float)newAttributes.MinMargins.BottomMils/1000);
int w = (int)(dpi * (float)newAttributes.GetMediaSize().WidthMils/1000) - leftMargin - rightMargin;
int h = (int)(dpi * (float)newAttributes.GetMediaSize().HeightMils/1000) - topMargin - bottomMargin;
scale = Math.Min((float)document.PageContentRect.Width()/w, (float)document.PageContentRect.Height()/h);
}
public override void OnWrite(PageRange[] pages, ParcelFileDescriptor destination,
CancellationSignal cancellationSignal, WriteResultCallback callback)
{
PrintedPdfDocument.Page page = document.StartPage(0);
page.Canvas.Scale(scale, scale);
view.Draw(page.Canvas);
document.FinishPage(page);
WritePrintedPdfDoc(destination);
document.Close();
document.Dispose();
callback.OnWriteFinished(pages);
}
void WritePrintedPdfDoc(ParcelFileDescriptor destination)
{
var javaStream = new Java.IO.FileOutputStream(destination.FileDescriptor);
var osi = new OutputStreamInvoker(javaStream);
using (var mem = new MemoryStream())
{
document.WriteTo(mem);
var bytes = mem.ToArray();
osi.Write(bytes, 0, bytes.Length);
}
}
}
'WebView'には、' PrintDocumentAdapter'を返す 'CreatePrintDocumentAdapter'というメソッドがあり、' PrintManager'インスタンスに渡されます。 – SushiHangover
@SushiHangover thatsネイティブAndroid WebView :(Xamarin.Forms WebViewには、アンドロイドのみのものがありません。フォームをネイティブに変換する方法を知っていますか? – rrr
ネイティブにアクセスする必要があります。 'WebView'コントロールには複数のオプションがあります...カスタムレンダラーを介して' native'コントロールを公開し、それを依存サービスに渡したり、ネイティブレンダラー自体にネイティブ印刷ルーチンを埋め込んだり、依存関係サービスを繰り返したりすることができます現在の 'Activity'(GetChildCount/GetChildAt/...)のすべての子ビューがネイティブのアンドロイド' WebView'を見つけて、 'CreatePrintDocumentAdapter'などを呼び出します。 – SushiHangover