problem sizing android view to standard pdf size

I'm trying to generate a pdf document from a dynamically built android view. No matter what I do the android view is not re-sizing to be properly drawn on the pdf. Also pdf's are I guess are sized in points, while the view is currently setup in pixels.


    private var heightInPixels = 1100
    private var widthInPixels = 850
    private val heightLetterPaperInPoints = 792
    private val widthLetterPaperInPoints  = 612

    private fun createPdf() {
        try {
            val data = viewModel.getData(info, requireContext())
            val view2: View =
                LayoutInflater.from(requireContext()).inflate(R.layout.pdf_layout, null)
            val titleTextView = view2.findViewById<TextView>(R.id.title)
            val selectionsContainer = view2.findViewById<LinearLayout>(R.id.selections_container)
            for (item in data) {
                val selectionViewBinding = ItemPdfSelectionBinding.inflate(layoutInflater)
                selectionViewBinding.itemTitle.text = item.title
                selectionViewBinding.selectionName.text = item.selectionName
                selectionsContainer.addView(selectionViewBinding.root)
            }
            val pageInfo =
                PageInfo.Builder(widthLetterPaperInPoints, heightLetterPaperInPoints, 1).create()
            val page = pdfDocument.startPage(pageInfo)
            view2.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (widthInPixels).toInt(),
                    View.MeasureSpec.UNSPECIFIED
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (heightInPixels).toInt(),
                    View.MeasureSpec.UNSPECIFIED
                )
            )
            view2.layout(0, 0, widthInPixels, heightInPixels)
            view2.draw(page.canvas)
            pdfDocument.finishPage(page)
        } catch (t: Throwable) {

        }
    }

I also tried:

view2.scaleX = .72 view2.scaleY = .72

before measuring the view and that also did nothing.

 The issue you're encountering might be due to the difference in unit of measurement between pixels and points. One approach you could take is to convert the view's dimensions from pixels to points to ensure it fits properly on the PDF page. You can do this using the following formula:

pixels = points * (dpi / 72)

Where dpi is the device's screen density in dots per inch, and 72 is the number of points per inch. You can get the device's screen density programmatically using the DisplayMetrics class.

Here's an example of how you could modify your code to resize the view to fit the PDF page:

scss
private fun createPdf() { try { val data = viewModel.getData(info, requireContext()) val view2: View = LayoutInflater.from(requireContext()).inflate(R.layout.pdf_layout, null) val titleTextView = view2.findViewById<TextView>(R.id.title) val selectionsContainer = view2.findViewById<LinearLayout>(R.id.selections_container) for (item in data) { val selectionViewBinding = ItemPdfSelectionBinding.inflate(layoutInflater) selectionViewBinding.itemTitle.text = item.title selectionViewBinding.selectionName.text = item.selectionName selectionsContainer.addView(selectionViewBinding.root) } val pageInfo = PageInfo.Builder(widthLetterPaperInPoints, heightLetterPaperInPoints, 1).create() val page = pdfDocument.startPage(pageInfo) val displayMetrics = requireContext().resources.displayMetrics val density = displayMetrics.densityDpi.toFloat() val widthInPoints = widthInPixels / (density / 72) val heightInPoints = heightInPixels / (density / 72) view2.measure( View.MeasureSpec.makeMeasureSpec(widthInPoints.toInt(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(heightInPoints.toInt(), View.MeasureSpec.EXACTLY) ) view2.layout(0, 0, view2.measuredWidth, view2.measuredHeight) view2.draw(page.canvas) pdfDocument.finishPage(page) } catch (t: Throwable) { } }

In this example, we first obtain the device's screen density in dots per inch using the DisplayMetrics class. We then calculate the width and height of the view in points using the formula above, and use these dimensions to measure the view. Finally, we layout the view using its measured dimensions, and draw it on the PDF page.

Note that we're using View.MeasureSpec.EXACTLY for the measure spec mode to ensure that the view is measured exactly to the specified dimensions.

Comments