我想使用 Android 的 PdfDocument 类通过滚动滚动视图的内容来生成 pdf 文档。
现在,正在生成正确的页数,但内容仅打印在 pdf 的第一页上。其他生成的页面保持空白。
public void toPdf(ScrollView view) {
PdfDocument document = new PdfDocument();
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
int totalHeight = scrollView.getChildAt(0).getHeight();
int pageCount = (int) Math.ceil((double) totalHeight / pageHeight);
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();
int savedContentOffset = view.getScrollY();
int savedContentInset = view.getPaddingBottom();
view.setClickable(false);
view.setVerticalScrollBarEnabled(false);
view.setHorizontalScrollBarEnabled(false);
view.setPadding(0, 0, 0, 0);
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
view.scrollTo(0, pageIndex * pageHeight);
view.draw(canvas);
document.finishPage(page);
if (pageIndex < pageCount - 1) {
pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, pageIndex + 2).create();
page = document.startPage(pageInfo);
canvas = page.getCanvas();
}
}
view.scrollTo(savedContentOffset, 0);
view.setPadding(0, 0, 0, savedContentInset);
view.setClickable(true);
view.setVerticalScrollBarEnabled(true);
view.setHorizontalScrollBarEnabled(true);
// save PDF to a file
savePdfDocument(document);
}
我验证了滚动视图的位置正在正确更新。我还尝试在每个滚动之间添加延迟,以确保视图的内容以 pdf 格式编写,但没有帮助。我无法弄清楚为什么除了第一页之外的其他页面上的内容没有被写入 pdf 格式。我在这里缺少什么?
我认为你的问题是滚动是通过画布翻译(平移画布)完成的,当你调用
view.scrollTo
时,你正在翻译屏幕的画布,但你然后要求视图将自己绘制到新的canvas
尚未应用平移翻译,但视图上的 ClipBounds 已设置。
因此滚动视图内容实际上是从第二页的底部绘制的。
绘制滚动视图类型视图内容的更好方法实际上是依次重新测量和布局滚动视图的所有子视图,然后将它们添加到绘制到每个页面的线性布局(如果它们适合)。
这更好,因为您不会像使用当前方法那样获得跨 pdf 页面分割的子视图。
示例中显示了重新测量然后布局到每个页面的线性布局的概念https://github.com/Zardozz/RecyclerviewPdf虽然这可能适用于 recyclerview,但概念将是相同的,除了相反迭代适配器从视图持有者创建每个视图时,您将迭代子视图。
例如
for(int index = 0; index < ((ViewGroup) viewGroup).getChildCount(); index++) {
View nextChild = ((ViewGroup) viewGroup).getChildAt(index);
}
如果需要,您还可以创建标准尺寸的 PDF 页面。