我需要取得視圖的總高度來產生 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 有兩種主要方法。
繪製所有內容,然後切片和切塊到多個頁面,使用這種方法,您可能會擁有在頁面之間分割的項目,例如一頁上某些文字行的上半部和另一頁的下半部使其無法閱讀。這不是一個好方法。
迭代父視圖的子視圖,測量每個子視圖,然後將它們新增到單一頁面的佈局中。透過這種方式,您可以獲得每個子視圖的大小,然後可以計算已新增的所有視圖的累積大小,以查看它是否對於您的頁面大小來說太大。如果太大,您將關閉 PDF 頁面並開始佈局到新頁面。這意味著項目不會跨頁面拆分(這樣好多了)。
https://www.php.cn/link/ea89621bee7c88b2c5be6681c8ef4906 是一個完整的範例,說明如何透過測量各個子視圖,從可捲動螢幕產生多頁PDF(在本例中,可捲動螢幕是一個回收視圖,但您可以以類似的方式迭代滾動視圖的子項目)。
請注意,A4 頁面的解析度非常低,因此實體螢幕的正常字體大小(或其他項目大小)可能會太大,因此您需要像通常情況下那樣調整這些大小不同螢幕尺寸的佈局)。還有另一種方法可以調整PDF 頁面的低分辨率,將其繪製為PDF 頁面大小的倍數,然後在PDF 畫布上設置比例以將其縮放回正確的大小,例如繪製到兩倍大的佈局,然後在繪製到PDF 頁面時將所有內容放回一半大小。
雖然您可能遇到的問題是您的 Textview 可能在一個區塊中包含的文本多於一頁所能容納的文本,但這些應該需要額外的處理,以創建兩個 Textview 而不是一個。
以上是如何取得視圖的總高度的詳細內容。更多資訊請關注PHP中文網其他相關文章!