首頁  >  文章  >  如何取得視圖的總高度

如何取得視圖的總高度

PHPz
PHPz轉載
2024-02-06 08:35:07652瀏覽
問題內容

我需要取得視圖的總高度來產生 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刪除