2015-11-26 55 views
6

我想创建一个简单的PDF文档使用Android本机PdfDocument类(从API 19)。我想要的是有一个XML布局文件,例如pdf_doc.xml,然后在创建PDF时对其进行充气。在pdf_doc.xml里面,我会看到一堆可以在代码中获取的视图,然后单独绘制到PdfDocuments页面上。问题是,这会创建一个损坏的PDF文件。另一方面,如果我只是在我的main_activity.xml(我在创建PDF时使用的活动的xml)中创建一个简单的TextView,并使用该TextView,它可以正常工作。Android PdfDocument损坏时,保存到外部存储

为什么TextView来自膨胀的布局或活动的布局有什么区别?我是否试图以错误的方式做到这一点?

仅供参考:以编程方式创建TextView时也失败。

以下是我的源代码。这两个功能在彼此之后立即被调用。第一个创建PDF,另一个保存。问题是在我看来,被称为内容,即时通讯膨胀的布局。如果我将该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

谢谢你提出了两个建设性的建议。我明天早上会试试看! –

+0

如果我希望布局只填充尽可能多的空间,那么measure()的参数是什么?最多? –

+0

@ThomasTeilmann:打我。我没有尝试过。我不确定是否有“尽可能多的空间”,因为没有父母。由于IIRC必须以像素为单位提供纸张大小,因此可能会使用相同数量的像素(或可能少一些)。 – CommonsWare