2

I'm trying to create a PDF file from a view that I create programatically. It seems that the pdf is created correctly only if the view is added to my main layout, but I don't want that. Here's my test code:

RelativeLayout layout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ImageView imgView = (ImageView) findViewById(R.id.imageView);
    mainView = (RelativeLayout) findViewById(R.id.main_layout); 

    layout = new RelativeLayout(this);

    RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams(800, 800);
    imgParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    imgParams.addRule(RelativeLayout.ALIGN_PARENT_START);

    ImageView newImg = new ImageView(this);
    newImg.setLayoutParams(imgParams);
    newImg.setImageDrawable(imgView.getDrawable());

    layout.addView(newImg);
}

private void create() {
    layout.layout(0, 0, 1000, 1000);

    layout.post(new Runnable() {
        @Override
        public void run() {
            createPdf();
        }
    });
}

private void createPdf() {
    OutputStream os = null;
    File file = null;

    PdfDocument pdfDoc = new PdfDocument();
    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(1000, 1000, 1).create();
    PdfDocument.Page page = pdfDoc.startPage(pageInfo);

    layout.draw(page.getCanvas());

    pdfDoc.finishPage(page);

    try {
        file = new File(Environment.getExternalStorageDirectory(), "page.pdf");
        os = new BufferedOutputStream(new FileOutputStream(file));
        pdfDoc.writeTo(os);
        pdfDoc.close();
        os.close();

    } catch (IOException e) {

    }
}

This creates an empty pdf. If I add these two lines of code in create(), it works:

    mainView.removeAllViews();
    mainView.addView(layout);

but I don't want to remove the content on the main view. How can I make this work?

Edit:

I have found a possible solution. For whatever reason it wants to attach to a view that is statically defined in xml. So define an empty viewgroup in xml which has an id. You get a reference in onCreate() then you can basically use the code from above, but instead you use addView() on this view. Oh and set the viewgroup to invisible since you don't want it to be displayed. I've only tested on one device however.

Daniel
  • 1,075
  • 2
  • 14
  • 26
  • If the whole thing is just an image, [print the image](http://developer.android.com/training/printing/photos.html). If the whole thing can be represented in HTML, [print the HTML](http://developer.android.com/training/printing/html-docs.html). Otherwise, you can try manually calling `measure()` and `layout()` on your `mainView`, to see if that helps. I am skeptical that sharing a `Drawable` between two `ImageView` widgets as you are will work in all cases, but you're welcome to keep trying it. – CommonsWare Dec 10 '15 at 12:12
  • @CommonsWare thank you, this was just an example. In reality my layout is more complex with multiple images and text views, some of which are not shown on the main page. I checked the `RelativeLayout` `width` and `height` in `createPdf()` and it's there. I don't understand why it doesn't work. Edit: I tried it with `getResouce().getDrawable()` but it still doesn't work. – Daniel Dec 10 '15 at 12:19

1 Answers1

1

layout.measure(1000, 1000); layout.layout(0, 0, 1000, 1000);

I was having similar problem and this fixed it for me.

Android: inflating a layout and writting it to PDF produces a blank PDF

Community
  • 1
  • 1
sasha
  • 343
  • 1
  • 6
  • 14