Maison >Java >Comment obtenir la hauteur totale d'une vue

Comment obtenir la hauteur totale d'une vue

PHPz
PHPzavant
2024-02-06 08:35:07670parcourir
Contenu de la question

J'ai besoin d'obtenir la hauteur totale de la vue pour générer un PDF afin de savoir combien de pages doivent être dessinées.

Je dois générer un PDF à l'aide du contenu de l'écran, qui possède un ScrollView contenant les données d'une base de données.

J'ai créé un projet de test pour cela, voir le code ci-dessous.

Même si je change le XML pour ajouter plus d'images, ce code me donne toujours le même numéro :

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();

            }
        });

Voici mon code PDF généré :

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
        }
    }

Voici mon fichier XML :

<?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>

@éditeur : Voici les liens vers ce que j'ai essayé: Android : hauteur totale de ScrollView

Comment savoir quand une mise en page est dessinée ?

@Edit2 : Voici un tutoriel pour créer un PDF (il ne génère qu'1 page, donc le code pour générer plus de pages est ce que j'ai trouvé autour) https://www.youtube.com/watch?v=-JC1PI-dSeE


Correct Answer


Le code vous donne toujours le même numéro car vous lui dites quel numéro donner et fixez le numéro à vous lui dites la taille donnée.

Lorsque vous définissez Measurespec sur EXACTEMENT selon docs

Vous forcez donc la taille de la vue à une taille incorrecte calculée en fonction de la taille de l'écran.

Lorsque vous dessinez une vue PDF, vous pouvez définir la page PDF sur une taille amusante qui correspond à votre écran, ou vous pouvez la définir sur un format de papier standard, tel que A4

Si vous choisissez une largeur non standard, vous pouvez également utiliser une hauteur non standard et n'avoir qu'une seule page. Ensuite, si l’utilisateur souhaitait l’imprimer, il devrait le diviser en pages de plusieurs largeurs et hauteurs. Du point de vue de l'utilisateur, il n'y a aucun avantage à utiliser plusieurs pages si vous visualisez simplement le PDF à l'écran

Je pense qu'il est préférable de s'en tenir à la taille de page standard du PDF, puis de traiter le PDF comme un écran basse résolution distinct, quelle que soit la taille physique de l'écran de l'appareil (ils peuvent faire défiler la page vers le haut, le bas, la gauche et la droite). )

Lorsque vous mesurez une seule vue, vous mesurez la vue entière et toutes ses sous-vues, vous ne pouvez pas mesurer des tranches (ce que vous voulez voir sur les deuxième et troisième pages).

Il existe deux manières principales de créer des PDF de plusieurs pages à partir de vues.

  1. Dessinez tout, puis découpez-le sur plusieurs pages. En utilisant cette méthode, vous pourriez avoir des éléments répartis entre les pages, comme la moitié supérieure de certaines lignes de texte sur une page et la moitié supérieure de certaines lignes sur une autre page. La partie inférieure le rend illisible. Ce n'est pas une bonne approche.

  2. Parcourez les sous-vues de la vue parent, mesurez chaque sous-vue et ajoutez-les à la mise en page d'une seule page. De cette façon, vous pouvez obtenir la taille de chaque sous-vue, puis calculer la taille cumulée de toutes les vues que vous avez ajoutées pour voir si elle est trop grande pour la taille de votre page. Si elle est trop volumineuse, vous fermerez la page PDF et commencerez à la mettre en page sur une nouvelle page. Cela signifie que les éléments ne sont pas répartis sur plusieurs pages (ce qui est bien mieux).

https://www.php.cn/link/ea89621bee7c88b2c5be6681c8ef4906 est un exemple complet de la façon de générer un PDF multipage à partir d'un écran déroulant en mesurant des sous-vues individuelles (dans ce cas, l'écran déroulant est une vue recyclée, mais vous pouvez parcourir les éléments enfants de la vue défilante de la même manière).

Veuillez noter que les pages A4 sont de très faible résolution, donc la taille de police normale (ou autre taille de projet) pour l'écran physique peut être trop grande, vous devrez donc redimensionner ces mises en page comme vous le feriez normalement pour différentes tailles d'écran). Il existe un autre moyen de redimensionner une page PDF en basse résolution, de la dessiner à un multiple de la taille de la page PDF, puis de définir l'échelle sur le canevas PDF pour la redimensionner à la taille correcte, par exemple en dessinant selon une mise en page double. aussi grand, puis redimensionnez le tout à la moitié de sa taille lorsque vous dessinez sur la page PDF.

Bien que le problème que vous puissiez rencontrer soit que votre Textview puisse contenir plus de texte dans un bloc que ne peut en contenir une page, ceux-ci devraient nécessiter un traitement supplémentaire pour créer deux Textviews au lieu d'une.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer