search
HomeJavaHow to get the total height of a view

Question content

I need to get the total height of the view to generate a PDF to know how many pages need to be drawn.

I need to generate a PDF using screen content, which has a ScrollView containing data from a database.

I created a test project for this, see the code below.

Even if I change the XML to add more images, this code always gives me the same number:

ViewTreeObserver vto2 = layout.getViewTreeObserver();
        vto2.addOnGlobalLayoutListener (new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    layout.getViewTreeObserver()
                            .removeOnGlobalLayoutListener(this);
                } else {
                    layout.getViewTreeObserver()
                            .removeGlobalOnLayoutListener(this);
                }
                int width  = layout.getMeasuredWidth();
                int height = layout.getMeasuredHeight();

            }
        });

This is my code to generate PDF:

public void convertXmlToPdf() {

        PdfDocument document = new PdfDocument();
        DisplayMetrics displayMetrics = new DisplayMetrics();

        int viewWidth = 1080;
        int viewHeight = 1920;

        int numPagina = 1;
        View view = LayoutInflater.from(this).inflate(R.layout.main_activity, null);

        view.measure(View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels * numPagina, View.MeasureSpec.EXACTLY));
        view.getMeasuredHeight();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            this.getDisplay().getRealMetrics(displayMetrics);
        } else
            this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        if(ViewCompat.isLaidOut(view)) {
            view.getHeight();
        }
        view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);

        Display display = getWindowManager().getDefaultDisplay();
        Point m_size = new Point();
        display.getSize(m_size);

        int m_height = m_size.y;

        **double totalPages = Math.ceil(Double.parseDouble(m_height + "") / Double.parseDouble(viewHeight + "")); //TODO <----- i can't get the real height number here**
//        double totalPages = 4;

        do {
            view = LayoutInflater.from(this).inflate(R.layout.main_activity, null);

            if(numPagina == 1) {
                view.measure(View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels * numPagina, View.MeasureSpec.EXACTLY));
            } else {
                view.measure(View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels * numPagina + (displayMetrics.heightPixels * numPagina - displayMetrics.heightPixels), View.MeasureSpec.EXACTLY)); //If i don't do this the next pages don't start from where they need
            }
            view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
            // Create a new PdfDocument instance

            view.getMeasuredHeight();

            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(displayMetrics.widthPixels, displayMetrics.heightPixels, numPagina).create();

            // Start a new page
            PdfDocument.Page page = document.startPage(pageInfo);

            // Get the Canvas object to draw on the page
            Canvas canvas = page.getCanvas();

            // Create a Paint object for styling the view
            Paint paint = new Paint();
            paint.setColor(Color.BLACK);

            // Draw the view on the canvas
            view.draw(canvas);

            // Finish the page
            document.finishPage(page);
            numPagina++;
        } while (numPagina <= totalPages);


        // Specify the path and filename of the output PDF file
        File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
        String fileName = "exampleXML.pdf";
        File filePath = new File(downloadsDir, fileName);

        try {
            // Save the document to a file
            FileOutputStream fos = new FileOutputStream(filePath);
            document.writeTo(fos);
            document.close();
            fos.close();
            // PDF conversion successful
            Toast.makeText(this, "XML to PDF Conversion Successful", Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            // Error occurred while converting to PDF
        }
    }

This is my XML file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:id="@+id/rootview">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Learn to Create PDF"
        android:textStyle="bold"
        android:textColor="@color/black"/>


    <Button
        android:id="@+id/btnCreatePdf"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Create PDF" />

    <Button
        android:id="@+id/btnXMLToPDF"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Convert XML View to PDF" />

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="1"
                android:textColor="@color/black" />

            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="360px"
                android:src="@drawable/logo_om"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="2"
                android:textColor="@color/black"/>

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="360px"
                android:src="@drawable/logo_om"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="3"
                android:textColor="@color/black"/>


            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="360px"
                android:src="@drawable/logo_om"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="4"
                android:textColor="@color/black"/>

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="360px"
                android:src="@drawable/logo_om"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="5"
                android:textColor="@color/black" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="360px"
                android:src="@drawable/logo_om"
                android:visibility="visible" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="30px"
                android:text="FINAL DO DOCUMENTO" />

        </LinearLayout>

    </ScrollView>


</LinearLayout>

@edit: Here are the links to what I've tried: Android: Total height of ScrollView

How to tell when the layout is drawn?

@Edit2: Here is a tutorial for creating a PDF (it only generates 1 page, so the code to generate more pages is what I found around) https://www.youtube.com/watch?v=-JC1PI-dSeE


Correct Answer


The code always gives you the same number as you told It gives you whatever number it wants, and fixes the number to the size you tell it to give it.

When you set Measurespec to EXACTLY according to the documentation

So you are forcing the view size to an incorrect size calculated based on the screen size.

When drawing a PDF view, you can set the PDF page to an interesting size that matches your screen, or you can set it to a standard paper size, such as A4

If you choose non-standard width, you can also use non-standard height and only have one page. Then, if the user wanted to print it, they would have to split it into pages of multiple widths and heights. From a user perspective, there is no benefit to using multiple pages if you are just viewing the PDF on the screen

I think it's better to stick with the standard page size of the PDF, and then treat the PDF as a separate low-resolution screen, independent of the physical screen size of the device (they can scroll the page up, down, left, and right)

When you measure a single view, you are measuring the entire view and all its subviews, you cannot measure slices (what you want to see on the second and third pages).

There are two main ways to create multi-page PDFs from views.

  1. Draw everything and then slice and dice it across multiple pages, using this approach you might have items that are split between pages, like the top half of certain lines of text on one page and The bottom half on another page makes it unreadable. This is not a good approach.

  2. Iterate over the parent view's subviews, measure each subview, and add them to the layout of a single page. This way you can get the size of each subview and then calculate the cumulative size of all the views you've added to see if it's too big for your page size. If it's too big, you'll close the PDF page and start laying out to a new page. This means items are not split across pages (which is much better).

https://www.php.cn/link/ea89621bee7c88b2c5be6681c8ef4906 is a complete example of how to generate a multi-page PDF from a scrollable screen by measuring individual subviews (in this case, A scrollable screen is a recycling view, but you can iterate over the scroll view's children in a similar way).

Please note that A4 pages have a very low resolution, so the normal font size (or other item size) for the physical screen may be too large, so you will need to resize the layout for these as you normally would for different screen sizes). There is another way to resize a PDF page for low resolution, draw it to a multiple of the PDF page size, and then set the scale on the PDF canvas to scale it back to the correct size, e.g. draw to a layout that is twice as big, Then scale everything back to half size when drawing to the PDF page.

While the problem you may encounter is that your Textview may contain more text in a block than can fit on one page, these should require additional processing to create two Textviews instead of one.

The above is the detailed content of How to get the total height of a view. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:stackoverflow. If there is any infringement, please contact admin@php.cn delete

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools