2015-11-26 10 views
6

私はAndroidsのネイティブPdfDocumentクラス(api 19から)を使用して簡単なPDFドキュメントを作成しようとしています。私が欲しいのは、例えばPDFファイルを作成するときにpdf_doc.xmlと呼ばれるXMLレイアウトファイルを作成し、それを膨張させることです。 pdf_doc.xml私はコード内に取り込まれた後、PdfDocumentsページに別々に描画される一連のビューを作成します。問題は、これが破損したPDFファイルを作成することです。一方外部のストレージに保存するとAndroidのPdfDocumentが破損する

私はちょうど私のmain_activity.xml(PDFを作成するときに私が使用している活動のXML)で、シンプルなのTextViewを作成して、代わりにそののTextViewを使用している場合、それが正常に動作します。

TextViewが膨大なレイアウトやアクティビティのレイアウトに由来するかどうかはなぜ違いますか?私はこれを間違った方法でやろうとしていますか?

FYI:プログラムでTextViewを作成するときにも失敗します。

以下は私のソースコードです。これら2つの関数は、互いに直後に呼び出されます。最初のものはPDFを作成し、もう1つは保存します。この問題は、という内容のと呼ばれる膨らんだレイアウトからのものです。代わりに、そのTextViewをActivityのXMLに入れてから、アクティビティから取得すると、act.findViewById(R.id.pdf_text);のように意図した通りに動作します。

コード:

public static PdfDocument createPdf(Activity act){ 
     PrintAttributes printAttrs = new PrintAttributes.Builder(). 
       setColorMode(PrintAttributes.COLOR_MODE_COLOR). 
       setMediaSize(PrintAttributes.MediaSize.ISO_A4). 
       setMinMargins(PrintAttributes.Margins.NO_MARGINS). 
       build(); 

     ViewGroup mainLayout = (ViewGroup) View.inflate(act, R.layout.pdf_doc, null); 

     int pageHeight = printAttrs.getMediaSize().getHeightMils()/1000 * 72; 
     int pageWidth = printAttrs.getMediaSize().getWidthMils()/1000 * 72; 

     PdfDocument document = new PrintedPdfDocument(act, printAttrs); 
     PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create(); 
     PdfDocument.Page page = document.startPage(pageInfo); 

     View content = mainLayout.findViewById(R.id.pdf_text); 
     content.draw(page.getCanvas()); 
     document.finishPage(page); 

     return document; 
    } 

    public static void saveFile(PdfDocument doc){ 
     String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(); 
     File myDir = new File(root + "/pdf_test"); 
     myDir.mkdirs(); 

     File file = new File(myDir, "test.pdf"); 

     if (file.exists()) { 
      file.delete(); 
     } 

     try { 
      FileOutputStream out = new FileOutputStream(file); 
      doc.writeTo(out); 
      doc.close(); 
      out.flush(); 
      out.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     String path = file.getAbsolutePath(); 
     Log.d("pdftest", "path: " + path); 
    } 
+0

@ FrankN.Stein多分私は十分にはっきりしませんでしたが、私は一度にレイアウト全体を描画するつもりはありません。私は単にレイアウトからTextViewを取り出して描画しようとしています。アクティビティが使用しているレイアウトからそれを取るのと比べて、それを行う際の違いはわかりません。 –

+0

いいえ、全くありません。私が言ったように、私は、アクティビティのXMLからTextViewを取る場合、私はそれをPdfDocumentのページのキャンバスに描画することができますが、私はプログラムで膨らんだレイアウトからTextViewでそれを行うことはできません? –

答えて

1

つの提案:

  1. あなたmainLayoutがゼロの高さと幅がゼロになりますので、(あなたが親にそれを膨らませていない)、手動で変更してみてください、それをレイアウトしますその上にmeasure()layout()をこの順番で呼んでください。レイアウトのサイズをピクセルで指定する必要があります。

  2. out.flush()の後、out.close()の後にout.getFd().sync()を呼び出します。私はこれがあなたの特定の問題を引き起こしているのではないかと疑っていますが、それはよい考えであり、傷つきそうもありません。

+0

2つの建設的な提案をありがとう。私は明日の朝にそれを試してみるよ! –

+0

レイアウトができるだけ多くのスペースを埋めるだけなら、measure()のパラメータは何ですか?せいぜい? –

+0

@ThomasTeilmann:私を打つ。私はそれを試していない。親がいないので、「可能な限り多くのスペースがある」とは確信していません。 IIRCでは、ピクセル単位で用紙サイズを指定する必要があるため、おそらくこれと同じ数のピクセルを使用します。 – CommonsWare

関連する問題