Çizim uygulamaları, sayfa düzeni uygulamaları ve grafik çıktısı gibi, güzel biçimde basılı sayfalar oluşturmak temel bir özelliktir. Bu durumda kullanarak bir resmi veya HTML belgesini yazdırabilirsiniz. Bu tür uygulamaların yazdırma çıktısı almak için yazı tipleri, metin akışı, sayfa sonları ve daha fazlası dahil olmak üzere ve grafik öğeleri dahil edilir.
Uygulamanız için tamamen özelleştirilmiş bir yazdırma çıktısı oluşturmak için daha fazlası gerekir en az 100 dolarlık bir yatırım riski var. Hedeflerinize ulaşmanız için yazdırma çerçevesiyle iletişim kurma, yazıcı ayarlarına ayarlama, sayfa öğelerini çizme ve birden fazla sayfada yazdırmayı yönetebilirsiniz.
Bu derste, yazdırma yöneticisi ile nasıl bağlantı kurduğunuzu, bir yazdırma adaptörünü nasıl oluşturacağınızı ve oluşturmak için kullanabilirsiniz.
Yazdırma yöneticisine bağlanma
Uygulamanız yazdırma işlemini doğrudan yönettiğinde, bir
Android yazdırma çerçevesine bağlanarak bir örnek almak için kullanıcınızın yazdırma isteği
PrintManager
sınıfı. Bu sınıf, bir yazdırma işi başlatmanızı sağlar
ve yazdırma yaşam döngüsünü başlatın. Aşağıdaki kod örneğinde, yazdırma yöneticisinin nasıl alınacağı gösterilmektedir
ve yazdırma işlemini başlatın.
Kotlin
private fun doPrint() { activity?.also { context -> // Get a PrintManager instance val printManager = context.getSystemService(Context.PRINT_SERVICE) as PrintManager // Set job name, which will be displayed in the print queue val jobName = "${context.getString(R.string.app_name)} Document" // Start a print job, passing in a PrintDocumentAdapter implementation // to handle the generation of a print document printManager.print(jobName, MyPrintDocumentAdapter(context), null) } }
Java
private void doPrint() { // Get a PrintManager instance PrintManager printManager = (PrintManager) getActivity() .getSystemService(Context.PRINT_SERVICE); // Set job name, which will be displayed in the print queue String jobName = getActivity().getString(R.string.app_name) + " Document"; // Start a print job, passing in a PrintDocumentAdapter implementation // to handle the generation of a print document printManager.print(jobName, new MyPrintDocumentAdapter(getActivity()), null); // }
Yukarıdaki örnek kod, bir yazdırma işinin nasıl adlandırılacağını ve yazdırma yaşam döngüsünün adımlarını işleyen PrintDocumentAdapter
sınıfının bir örneğinin nasıl ayarlanacağını gösterir. İlgili içeriği oluşturmak için kullanılan
nasıl uygulanması gerektiğini bir sonraki bölümde ele alacağız.
Not: print()
yöntemi bir PrintAttributes
nesnesi alır. Bu parametreyi şunlar için kullanabilirsiniz:
önceki yazdırma döngüsüne göre yazdırma çerçevesine ipuçları ve önceden ayarlanmış seçenekler sağlar
Böylece kullanıcı deneyimini iyileştirebilirsiniz. Bu parametreyi,
yönü yatay olarak ayarlamak gibi, yazdırılan içeriğe daha uygun
o yönde bir fotoğraf bastırın.
Yazdırma adaptörü oluşturma
Bir yazdırma adaptörü, Android yazdırma çerçevesiyle etkileşime girer ve yazdırır. Bu işlem, kullanıcıların oluşturmadan önce yazıcıları ve yazdırma seçeneklerini belirlemesini gerektirir yazdıracak bir doküman. Bu seçimler kullanıcı tercihine göre nihai sonucu etkileyebilir farklı çıkış özelliklerine, farklı sayfa boyutlarına veya farklı sayfa yönlerine sahip yazıcılar. Bu seçimler yapılırken, yazdırma çerçevesi bağdaştırıcınızdan bir yerleşim düzeni oluşturmasını ve son çıktıya hazırlanmak için belgeyi yazdırmalıdır. Kullanıcı yazdır düğmesine dokunduğunda, çerçeve Basılı dokümanın son halini alır ve çıktı almak için bunu bir baskı sağlayıcısına iletir. Yazdırma sırasında Kullanıcılar yazdırma işlemini iptal etmeyi seçebilir. Dolayısıyla, yazdırma adaptörünüz de ve iptal isteklerine tepki verebilir.
PrintDocumentAdapter
soyut sınıfı,
dört ana geri çağırma yöntemi vardır. Aşağıdaki yöntemleri uygulamanız gerekir
kullanmanı öneririz:
onStart()
- Şu saatte bir kez arandı: olması gerekir. Uygulamanızda tek seferlik hazırlık görevleri varsa örneğin, yazdırılacak verilerin anlık görüntüsünü almak gibi işlemleri burada yürütebilirsiniz. Uygulama bu yöntemi kullanmanız gerekmez.onLayout()
- Her seferinde aranır Kullanıcı, çıkışı etkileyen bir yazdırma ayarını (örneğin, farklı bir sayfa boyutu, veya sayfa yönü gibi özellikler içerir. Bu da uygulamanıza sayfa düzeninin düzenini çok kolay olur. Bu yöntem en azından, beklenen sayfa sayısını döndürmelidir yer alır.onWrite()
- Yazdırılmak üzere çağrıldı bir dosyaya ekleyebilirsiniz. Bu yöntem her aramadan sonra bir veya daha fazlaonLayout()
arama.onFinish()
- Sonda bir kez arandı adımlarından biridir. Uygulamanızda gerçekleştirilmesi gereken tek seferlik ayırma görevleri varsa burada yürütmeliyiz. Bağdaştırıcınızda bu yöntemi uygulamanız gerekmez.
Aşağıdaki bölümlerde, düzen ve yazma yöntemlerinin nasıl uygulanacağı açıklanmaktadır. çalışması açısından kritik öneme sahip.
Not: Bu bağdaştırıcı yöntemleri, uygulamanızın ana iş parçacığında çağrılır. Eğer
uygulamanızda bu yöntemlerin yürütülmesinin önemli ölçüde harcama yapmasını
bunları ayrı bir iş parçacığında yürütülecek şekilde uygulayın. Örneğin,
ya da basılı doküman yazmanın işleyiş şekli ayrı AsyncTask
nesneleridir.
Yazdırma dokümanı bilgilerini hesapla
PrintDocumentAdapter
sınıfının bir uygulamasında,
oluşturduğu belgenin türünü belirtebilmeli ve toplam dosya sayısını hesaplayabilmeli
yazdırma işi için sayfa sayısı, yazdırılan sayfa boyutu hakkında bilgi.
onLayout()
yönteminin
adaptör bu hesaplamaları yapar ve beklenen çıktısı hakkında bilgi sağlar.
PrintDocumentInfo
sınıfındaki bir yazdırma işi (ör. sayfa sayısı ve
İçerik türü. Aşağıdaki kod örneğinde, PrintDocumentAdapter
için onLayout()
yönteminin temel bir uygulaması gösterilmektedir:
Kotlin
override fun onLayout( oldAttributes: PrintAttributes?, newAttributes: PrintAttributes, cancellationSignal: CancellationSignal?, callback: LayoutResultCallback, extras: Bundle? ) { // Create a new PdfDocument with the requested page attributes pdfDocument = PrintedPdfDocument(activity, newAttributes) // Respond to cancellation request if (cancellationSignal?.isCanceled == true) { callback.onLayoutCancelled() return } // Compute the expected number of printed pages val pages = computePageCount(newAttributes) if (pages > 0) { // Return print information to print framework PrintDocumentInfo.Builder("print_output.pdf") .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT) .setPageCount(pages) .build() .also { info -> // Content layout reflow is complete callback.onLayoutFinished(info, true) } } else { // Otherwise report an error to the print framework callback.onLayoutFailed("Page count calculation failed.") } }
Java
@Override public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle metadata) { // Create a new PdfDocument with the requested page attributes pdfDocument = new PrintedPdfDocument(getActivity(), newAttributes); // Respond to cancellation request if (cancellationSignal.isCanceled() ) { callback.onLayoutCancelled(); return; } // Compute the expected number of printed pages int pages = computePageCount(newAttributes); if (pages > 0) { // Return print information to print framework PrintDocumentInfo info = new PrintDocumentInfo .Builder("print_output.pdf") .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT) .setPageCount(pages) .build(); // Content layout reflow is complete callback.onLayoutFinished(info, true); } else { // Otherwise report an error to the print framework callback.onLayoutFailed("Page count calculation failed."); } }
onLayout()
yöntemi yürütülebilir
üç sonucu vardır: bu sonucun hesaplanması, iptal edilmesi veya
düzeni tamamlanamıyor. İlgili kişiyi çağırarak bu sonuçlardan birini belirtmeniz gerekir
yöntemini PrintDocumentAdapter.LayoutResultCallback
nesnesinin içinde tutun.
Not: Boole parametresinden
onLayoutFinished()
yöntemi, düzen içeriğinin gerçekten değişip değişmediğini gösterir
son talepten bu yana. Bu parametreyi doğru şekilde ayarlamak, yazdırma çerçevesinin
onWrite()
yöntemini gereksiz yere çağırmak,
temelde, önceden yazılmış basılı dokümanı önbelleğe almak ve performansı artırmaktır.
onLayout()
ana işi
yazıcının özelliklerine göre çıktı olarak görülmesi beklenen sayfa sayısını hesaplar.
Bu sayıyı nasıl hesaplayacağınız büyük ölçüde uygulamanızın bu sayfalarla ilgili sayfaları nasıl düzenlediğine bağlıdır.
yazdırma. Aşağıdaki kod örneğinde, sayfa sayısının
baskı yönüne göre belirlenir:
Kotlin
private fun computePageCount(printAttributes: PrintAttributes): Int { var itemsPerPage = 4 // default item count for portrait mode val pageSize = printAttributes.mediaSize if (!pageSize.isPortrait) { // Six items per page in landscape orientation itemsPerPage = 6 } // Determine number of print items val printItemCount: Int = getPrintItemCount() return Math.ceil((printItemCount / itemsPerPage.toDouble())).toInt() }
Java
private int computePageCount(PrintAttributes printAttributes) { int itemsPerPage = 4; // default item count for portrait mode MediaSize pageSize = printAttributes.getMediaSize(); if (!pageSize.isPortrait()) { // Six items per page in landscape orientation itemsPerPage = 6; } // Determine number of print items int printItemCount = getPrintItemCount(); return (int) Math.ceil(printItemCount / itemsPerPage); }
Basılı doküman dosyası yazma
Yazdırma çıktısını bir dosyaya yazma zamanı geldiğinde, Android yazdırma çerçevesi uygulamanızın PrintDocumentAdapter
sınıfının onWrite()
yöntemini çağırır. Yöntemin parametreleri, eklenmesi gereken sayfaları
çıktı dosyasıyla birlikte hazırlanır. Daha sonra, bu yöntemi uyguladığınızda her
istenen içerik sayfasını çok sayfalı bir PDF belge dosyasına dönüştürmenize olanak tanır. Bu işlem tamamlandığında
geri çağırma nesnesinin onWriteFinished()
yöntemini çağırın.
Not: Android yazdırma çerçevesi, onWrite()
yöntemini her cihaz için bir veya daha fazla kez çağırabilir.
onLayout()
araması. Bu nedenle,
Boole parametresinin ayarlanmasında
Yazdırma içeriği düzeni değişmediğinde false
olarak onLayoutFinished()
yöntemini kullanmak,
Böylece basılı dokümanın gereksiz şekilde yeniden yazılmasını önleyebilirsiniz.
Not: Boole parametresinden
onLayoutFinished()
yöntemi, düzen içeriğinin gerçekten değişip değişmediğini gösterir
son talepten bu yana. Bu parametreyi doğru şekilde ayarlamak, yazdırma çerçevesinin
onLayout()
yöntemini gereksiz yere çağırmak,
temelde, önceden yazılmış basılı dokümanı önbelleğe almak ve performansı artırmaktır.
Aşağıdaki örnekte, PDF dosyası oluşturmak için PrintedPdfDocument
sınıfının kullanıldığı bu işlemin temel mekanizması gösterilmektedir:
Kotlin
override fun onWrite( pageRanges: Array<out PageRange>, destination: ParcelFileDescriptor, cancellationSignal: CancellationSignal?, callback: WriteResultCallback ) { // Iterate over each page of the document, // check if it's in the output range. for (i in 0 until totalPages) { // Check to see if this page is in the output range. if (containsPage(pageRanges, i)) { // If so, add it to writtenPagesArray. writtenPagesArray.size() // is used to compute the next output page index. writtenPagesArray.append(writtenPagesArray.size(), i) pdfDocument?.startPage(i)?.also { page -> // check for cancellation if (cancellationSignal?.isCanceled == true) { callback.onWriteCancelled() pdfDocument?.close() pdfDocument = null return } // Draw page content for printing drawPage(page) // Rendering is complete, so page can be finalized. pdfDocument?.finishPage(page) } } } // Write PDF document to file try { pdfDocument?.writeTo(FileOutputStream(destination.fileDescriptor)) } catch (e: IOException) { callback.onWriteFailed(e.toString()) return } finally { pdfDocument?.close() pdfDocument = null } val writtenPages = computeWrittenPages() // Signal the print framework the document is complete callback.onWriteFinished(writtenPages) ... }
Java
@Override public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal, final WriteResultCallback callback) { // Iterate over each page of the document, // check if it's in the output range. for (int i = 0; i < totalPages; i++) { // Check to see if this page is in the output range. if (containsPage(pageRanges, i)) { // If so, add it to writtenPagesArray. writtenPagesArray.size() // is used to compute the next output page index. writtenPagesArray.append(writtenPagesArray.size(), i); PdfDocument.Page page = pdfDocument.startPage(i); // check for cancellation if (cancellationSignal.isCanceled()) { callback.onWriteCancelled(); pdfDocument.close(); pdfDocument = null; return; } // Draw page content for printing drawPage(page); // Rendering is complete, so page can be finalized. pdfDocument.finishPage(page); } } // Write PDF document to file try { pdfDocument.writeTo(new FileOutputStream( destination.getFileDescriptor())); } catch (IOException e) { callback.onWriteFailed(e.toString()); return; } finally { pdfDocument.close(); pdfDocument = null; } PageRange[] writtenPages = computeWrittenPages(); // Signal the print framework the document is complete callback.onWriteFinished(writtenPages); ... }
Bu örnekte, PDF sayfası içeriği oluşturma yetkisi drawPage()
adlı iş ortağına verilir
yöntemidir.
Düzende olduğu gibi onWrite()
yürütmesi
yönteminin üç sonucu olabilir: standartların tamamlanması, iptal veya başarısız olması.
içerik yazılamıyor. Bu sonuçlardan birini,
PrintDocumentAdapter.WriteResultCallback
nesnesinin uygun yöntemini çağırın.
Not: Yazdırmak için doküman oluşturmak yoğun kaynak kullanan bir işlem olabilir. İçinde
uygulamanızın ana kullanıcı arayüzü iş parçacığının engellenmesini önlemek için
sayfa oluşturma ve yazma işlemlerini ayrı bir iş parçacığında yapmak, örneğin
AsyncTask
içinde
Eşzamansız görevler gibi yürütme ileti dizileriyle çalışma hakkında daha fazla bilgi için
bkz. Süreçler
ve İleti dizileri'dir.
Çizim PDF sayfası içeriği
Uygulamanız yazdırıldığında, uygulamanızın bir PDF belgesi oluşturması ve bunu şuraya iletmesi gerekir:
Android yazdırma çerçevesidir. Bunun için herhangi bir PDF oluşturma kitaplığını kullanabilirsiniz
amaçlanıyor. Bu derste, PrintedPdfDocument
sınıfının nasıl kullanılacağı gösterilmektedir
içeriğinizden PDF sayfaları oluşturun.
PrintedPdfDocument
sınıfı Canvas
kullanıyor
nesne çizen bir nesnedir. Bu nesne, etkinlik düzeni üzerinde çizim yapmaya benzer. Çizim yapabilirsiniz
öğeleri yazdırılan sayfadaki Canvas
çizim yöntemlerini kullanarak yapar. Aşağıdakiler
örnek kod, bu öğeler kullanılarak PDF dokümanı sayfasına bazı basit öğelerin nasıl çizileceğini gösterir
yöntemleri:
Kotlin
private fun drawPage(page: PdfDocument.Page) { page.canvas.apply { // units are in points (1/72 of an inch) val titleBaseLine = 72f val leftMargin = 54f val paint = Paint() paint.color = Color.BLACK paint.textSize = 36f drawText("Test Title", leftMargin, titleBaseLine, paint) paint.textSize = 11f drawText("Test paragraph", leftMargin, titleBaseLine + 25, paint) paint.color = Color.BLUE drawRect(100f, 100f, 172f, 172f, paint) } }
Java
private void drawPage(PdfDocument.Page page) { Canvas canvas = page.getCanvas(); // units are in points (1/72 of an inch) int titleBaseLine = 72; int leftMargin = 54; Paint paint = new Paint(); paint.setColor(Color.BLACK); paint.setTextSize(36); canvas.drawText("Test Title", leftMargin, titleBaseLine, paint); paint.setTextSize(11); canvas.drawText("Test paragraph", leftMargin, titleBaseLine + 25, paint); paint.setColor(Color.BLUE); canvas.drawRect(100, 100, 172, 172, paint); }
PDF sayfasında çizim yapmak için Canvas
kullanılırken öğeler şurada belirtilir:
punto gibi, yani bir inçin 1/72'si. Boyutu belirtmek için bu ölçü birimini kullandığınızdan emin olun
görebilirsiniz. Çizilen elemanların konumlandırılması için koordinat sistemi 0,0 noktasından başlar
tıklayın.
İpucu: Canvas
nesnesi yazdırmanıza olanak tanır
bir PDF dokümanının kenarına yerleştirirseniz, birçok yazıcı bir dokümanın kenarının kenarına yazdıramaz.
bir kağıt parçasına dikkat edin. Sayfanın yazdırılamayan kenarlarını da hesaba kattığınızdan emin olun.
bu dersle basılı bir doküman oluşturacaksınız.