首页  >  文章  >  如何获取视图的总高度

如何获取视图的总高度

PHPz
PHPz转载
2024-02-06 08:35:07649浏览
问题内容

我需要获取视图的总高度来生成 PDF,以了解需要绘制的页数。

我需要使用屏幕内容生成 PDF,其中有一个包含来自数据库的数据的 ScrollView。

我为此创建了一个测试项目,请参阅下面的代码。

即使我更改 XML 添加更多图像,此代码也总是给我相同的数字:

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

            }
        });

这是我的生成 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
        }
    }

这是我的 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>

@编辑: 这是我尝试过的链接: Android:ScrollView的总高度

如何判断布局何时绘制?

@Edit2:这是创建 PDF 的教程(它只生成 1 页,因此生成更多页面的代码是我在周围找到的) https://www.youtube.com/watch?v=-JC1PI-dSeE


正确答案


代码总是给你相同的数字,因为你告诉它要给出什么数字,并将数字固定为你告诉它给出的大小。

当您根据文档将 Measurespec 设置为 EXACTLY 时

因此,您将视图尺寸强制设置为根据屏幕尺寸计算出的不正确尺寸。

在绘制 PDF 视图时,您可以将 PDF 页面设置为与屏幕相匹配的有趣尺寸,也可以将其设置为标准纸张尺寸,例如A4

如果您选择非标准宽度,那么您也可以使用非标准高度并且只有一页。然后,如果用户想要打印它,他们将不得不将其分成多个宽度和高度的页面。从用户的角度来看,如果只是在屏幕上查看 PDF,那么使用多个页面没有任何好处

我认为最好坚持使用 PDF 的标准页面大小,然后将 PDF 视为一个单独的低分辨率屏幕,与设备的物理屏幕尺寸无关(他们可以上下左右滚动页面)和右)

当您测量单个视图时,您正在测量整个视图及其所有子视图,您无法测量切片(您想要在第二页和第三页上看到的内容)。

从视图创建多页 PDF 有两种主要方法。

  1. 绘制所有内容,然后切片和切块到多个页面,使用这种方法,您可能会拥有在页面之间分割的项目,例如一页上某些文本行的上半部分和另一页上的下半部分使其无法阅读。这不是一个好方法。

  2. 迭代父视图的子视图,测量每个子视图,然后将它们添加到单个页面的布局中。通过这种方式,您可以获得每个子视图的大小,然后可以计算已添加的所有视图的累积大小,以查看它是否对于您的页面大小来说太大。如果太大,您将关闭 PDF 页面并开始布局到新页面。这意味着项目不会跨页面拆分(这样好多了)。

https://www.php.cn/link/ea89621bee7c88b2c5be6681c8ef4906 是一个完整的示例,说明如何通过测量各个子视图,从可滚动屏幕生成多页 PDF(在本例中,可滚动屏幕是一个回收视图,但您可以以类似的方式迭代滚动视图的子项目)。

请注意,A4 页面的分辨率非常低,因此物理屏幕的正常字体大小(或其他项目大小)可能会太大,因此您需要像通常情况下那样调整这些大小不同屏幕尺寸的布局)。还有另一种方法可以调整 PDF 页面的低分辨率,将其绘制为 PDF 页面大小的倍数,然后在 PDF 画布上设置比例以将其缩放回正确的大小,例如绘制到两倍大的布局,然后在绘制到 PDF 页面时将所有内容缩放回一半大小。

虽然您可能遇到的问题是您的 Textview 可能在一个块中包含的文本多于一页所能容纳的文本,但这些应该需要额外的处理,以创建两个 Textview 而不是一个。

以上是如何获取视图的总高度的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除