经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android项目实战(六十一):pdf文件用图片方式预览
来源:cnblogs  作者:听着music睡  时间:2020/12/21 14:45:48  对本文有异议

前言:

Android不支持pdf的在线预览,网上有多种预览pdf的实现方式,点此查看总结

这里实现一种先下载pdf文件到本地,再将文件转成图片显示的的操作 

一个工具类:

  1. import android.app.Application;
  2. import android.arch.lifecycle.AndroidViewModel;
  3. import android.arch.lifecycle.LiveData;
  4. import android.arch.lifecycle.MutableLiveData;
  5. import android.graphics.Bitmap;
  6. import android.graphics.pdf.PdfRenderer;
  7. import android.os.ParcelFileDescriptor;
  8. import android.support.annotation.WorkerThread;
  9. import android.util.Log;
  10. import android.widget.ImageView;
  11. import java.io.File;
  12. import java.io.IOException;
  13. import java.util.concurrent.Executor;
  14. import java.util.concurrent.Executors;
  15. import java.util.concurrent.TimeUnit;
  16. import info.ecloud.core.util.ToastUtils;
  17. import info.ecloud.merchant.app.BaseObserve;
  18. import io.reactivex.Observable;
  19. import io.reactivex.android.schedulers.AndroidSchedulers;
  20. import io.reactivex.schedulers.Schedulers;
  21. public class PdfRendererBasicViewModel extends AndroidViewModel {
  22. private static final String TAG = "PdfRendererBasic";
  23. /**
  24. * The filename of the PDF.
  25. */
  26. private static final String FILENAME = "sample.pdf";
  27. private final MutableLiveData<PageInfo> mPageInfo = new MutableLiveData<>();
  28. private final MutableLiveData<Bitmap> mPageBitmap = new MutableLiveData<>();
  29. private final MutableLiveData<Boolean> mPreviousEnabled = new MutableLiveData<>();
  30. private final MutableLiveData<Boolean> mNextEnabled = new MutableLiveData<>();
  31. private final Executor mExecutor;
  32. private ParcelFileDescriptor mFileDescriptor;
  33. private PdfRenderer mPdfRenderer;
  34. private PdfRenderer.Page mCurrentPage;
  35. private boolean mCleared;
  36. public File pdfFile ;
  37. public ImageView pdfView ;
  38. @SuppressWarnings("unused")
  39. public PdfRendererBasicViewModel(Application application , File pdfFile , ImageView pdfView) {
  40. this(application, false);
  41. this.pdfFile = pdfFile;
  42. this.pdfView = pdfView;
  43. }
  44. PdfRendererBasicViewModel(Application application, boolean useInstantExecutor) {
  45. super(application);
  46. if (useInstantExecutor) {
  47. mExecutor = Runnable::run;
  48. } else {
  49. mExecutor = Executors.newSingleThreadExecutor();
  50. }
  51. mExecutor.execute(() -> {
  52. try {
  53. openPdfRenderer();
  54. showPage(0);
  55. if (mCleared) {
  56. closePdfRenderer();
  57. }
  58. } catch (IOException e) {
  59. Log.e(TAG, "Failed to open PdfRenderer", e);
  60. }
  61. });
  62. }
  63. @Override
  64. protected void onCleared() {
  65. super.onCleared();
  66. mExecutor.execute(() -> {
  67. try {
  68. closePdfRenderer();
  69. mCleared = true;
  70. } catch (IOException e) {
  71. Log.i(TAG, "Failed to close PdfRenderer", e);
  72. }
  73. });
  74. }
  75. public LiveData<PageInfo> getPageInfo() {
  76. return mPageInfo;
  77. }
  78. public LiveData<Bitmap> getPageBitmap() {
  79. Log.i("xqxinfo","bitmap==>"+(mPageBitmap==null));
  80. return mPageBitmap;
  81. }
  82. public LiveData<Boolean> getPreviousEnabled() {
  83. return mPreviousEnabled;
  84. }
  85. public LiveData<Boolean> getNextEnabled() {
  86. return mNextEnabled;
  87. }
  88. void showPrevious() {
  89. if (mPdfRenderer == null || mCurrentPage == null) {
  90. return;
  91. }
  92. final int index = mCurrentPage.getIndex();
  93. if (index > 0) {
  94. mExecutor.execute(() -> showPage(index - 1));
  95. }
  96. }
  97. public void showNext() {
  98. if (mPdfRenderer == null || mCurrentPage == null) {
  99. return;
  100. }
  101. final int index = mCurrentPage.getIndex();
  102. if (index + 1 < mPdfRenderer.getPageCount()) {
  103. mExecutor.execute(() -> showPage(index + 1));
  104. }
  105. }
  106. public void showLast() {
  107. if (mPdfRenderer == null || mCurrentPage == null) {
  108. return;
  109. }
  110. final int index = mCurrentPage.getIndex();
  111. if (index - 1 >=0) {
  112. mExecutor.execute(() -> showPage(index - 1));
  113. }
  114. }
  115. @WorkerThread
  116. private void openPdfRenderer() throws IOException {
  117. final File file = pdfFile;
  118. if (!file.exists()) {
  119. ToastUtils.showLong("文件预览失败");
  120. return;
  121. }
  122. Log.i("xqxinfo","file->"+file.getAbsolutePath());
  123. mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
  124. if (mFileDescriptor != null) {
  125. mPdfRenderer = new PdfRenderer(mFileDescriptor);
  126. }
  127. }
  128. @WorkerThread
  129. private void closePdfRenderer() throws IOException {
  130. if (mCurrentPage != null) {
  131. mCurrentPage.close();
  132. }
  133. if (mPdfRenderer != null) {
  134. mPdfRenderer.close();
  135. }
  136. if (mFileDescriptor != null) {
  137. mFileDescriptor.close();
  138. }
  139. }
  140. @WorkerThread
  141. private void showPage(int index) {
  142. // Make sure to close the current page before opening another one.
  143. if (null != mCurrentPage) {
  144. mCurrentPage.close();
  145. }
  146. // Use `openPage` to open a specific page in PDF.
  147. mCurrentPage = mPdfRenderer.openPage(index);
  148. Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
  149. Bitmap.Config.ARGB_8888);
  150. // Here, we render the page onto the Bitmap.
  151. // To render a portion of the page, use the second and third parameter. Pass nulls to get
  152. // the default result.
  153. // Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
  154. mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_PRINT);
  155. mPageBitmap.postValue(bitmap);
  156. Observable.timer(10, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.io())
  157. .observeOn(AndroidSchedulers.mainThread())
  158. .subscribe(new BaseObserve<Long>() {
  159. @Override
  160. public void onNext(Long aLong) {
  161. pdfView.setImageBitmap(bitmap);
  162. }
  163. });
  164. final int count = mPdfRenderer.getPageCount();
  165. mPageInfo.postValue(new PageInfo(index, count));
  166. mPreviousEnabled.postValue(index > 0);
  167. mNextEnabled.postValue(index + 1 < count);
  168. }
  169. static class PageInfo {
  170. final int index;
  171. final int count;
  172. PageInfo(int index, int count) {
  173. this.index = index;
  174. this.count = count;
  175. }
  176. }
  177. }

 

使用方法:

  1. public PdfRendererBasicViewModel(Application application , File pdfFile , ImageView pdfView)

 

注意,因为是图片方式显示,依赖于一个ImageView , 每次只显示pdf一页的数据预览,额外提供上一页、下一页的方法使用

 

 这里只提供基本使用,可以自行拓展功能,不限于图片缩放,多页展示等

 

原文链接:http://www.cnblogs.com/xqxacm/p/14148639.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号