【问题标题】:How can i display a PDF file in an Android ImageView如何在 Android ImageView 中显示 PDF 文件
【发布时间】:2016-10-13 11:16:56
【问题描述】:

是否可以在 Android 视图中显示巨大的 pdf 文件?

我只需要能够显示它,通过捏合和缩放以及这些天在 ImageViews 中实现的其他正常功能。

【问题讨论】:

    标签: java android pdf


    【解决方案1】:

    共有三个开源库,它们组合在一起,可以满足您的需求。所有都获得了 Apache V2(或 Beer-Ware 许可证)的许可!

    请注意,需要 V21 或更高版本。但如果需要,您可以使用 if 语句和 Intent 作为后备。

    1. Subsampling-scale-image-view:“Android 的自定义图像视图,专为照片库和显示大图而设计”
    2. Subsampling-pdf-decoder: "用于二次采样比例图像视图的 pdf 解码器库"
    3. VerticalViewPager:这是可选的,但我认为您想要上下滚动而不是左右滚动。

    如何实现这一点的例子,在解码器库的示例中给出。

    1.) Gradle 依赖项

    repositories {
      mavenCentral()
      jcenter()
    
      //decoder library, will soon be on jcenter 
      maven { url 'https://dl.bintray.com/n42/maven'} 
    }
    
    dependencies {
      compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0'
      compile 'com.github.castorflex.verticalviewpager:library:19.0.1'
      compile 'de.number42:subsampling-pdf-decoder:0.1.0@aar'
    }
    

    2.) 实现一个PagerAdapter,你可以使用这个

    public class PDFPagerAdapter extends PagerAdapter {
      /**
       * context for the view
       */
      private Context context;
    
      /**
       * pdf file to show
       */
      private File file;
    
      /**
       * file descriptor of the PDF
       */
      private ParcelFileDescriptor mFileDescriptor;
    
      /**
       * this scale sets the size of the {@link PdfRenderer.Page} in the {@link
       * PDFRegionDecoder}.
       * Since it rescales the picture, it also sets the possible zoom level.
       */
      private float scale;
    
      /**
       * this renderer is only used to count the pages
       */
      private PdfRenderer renderer;
    
      /**
       * @param file the pdf file
       */
      public PDFPagerAdapter(Context context, File file) {
        super();
        this.context = context;
        this.file = file;
        this.scale = 8;
        try {
          mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
          renderer = new PdfRenderer(mFileDescriptor);
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    
      /**
       * Instantiate an item. Therefor a {@link SubsamplingScaleImageView} with special decoders is
       * initialized and rendered.
       *
       * @param container isn't used here
       * @param position the current pdf page position
       */
      public Object instantiateItem(ViewGroup container, int position) {
    
        SubsamplingScaleImageView imageView = new SubsamplingScaleImageView(context);
    
        // the smaller this number, the smaller the chance to get an "outOfMemoryException"
        // still, values lower than 100 really do affect the quality of the pdf picture
        int minimumTileDpi = 120;
        imageView.setMinimumTileDpi(minimumTileDpi);
    
        //sets the PDFDecoder for the imageView
        imageView.setBitmapDecoderFactory(() -> new PDFDecoder(position, file, scale));
    
        //sets the PDFRegionDecoder for the imageView
        imageView.setRegionDecoderFactory(() -> new PDFRegionDecoder(position, file, scale));
    
        ImageSource source = ImageSource.uri(file.getAbsolutePath());
    
        imageView.setImage(source);
    
        container.addView(imageView);
        return imageView;
      }
    
      /**
       * gets the pdf site count
       *
       * @return pdf site count
       */
      public int getCount() {
        return renderer.getPageCount();
      }
    
      @Override public void destroyItem(ViewGroup container, int position, Object view) {
        container.removeView((View) view);
      }
    
      @Override public boolean isViewFromObject(View view, Object object) {
        return view == object;
      }
    }
    

    3.) 为 VerticalViewPager 启动和设置适配器

    VerticalViewPager pager = (VerticalViewPager) findViewById(R.id.pager);
    File pdfFile = ....
    
    PDFPagerAdapter pagerAdapter = new PDFPagerAdapter(this,pdfFile);
    pager.setAdapter(pagerAdapter);
    

    【讨论】:

      【解决方案2】:

      您可以为此使用 webview,并且很容易实现。这样做

       @SuppressLint("NewApi")
          private void startWebView(String url) {
      
              // Create new webview Client to show progress dialog
              // When opening a url or click on link
              // Javascript inabled on webview
              web.getSettings().setJavaScriptEnabled(true);
              web.getSettings().setBuiltInZoomControls(true);
              web.getSettings().setDisplayZoomControls(false);
              web.getSettings().setLoadWithOverviewMode(true);
              web.getSettings().setUseWideViewPort(true);
      
              web.getSettings().setDomStorageEnabled(true);
              web.setWebChromeClient(new WebChromeClient());
      //        web.getSettings().setPluginState(WebSettings.PluginState.ON);
              web.setWebViewClient(new WebViewClient() {
                  ProgressDialog progressDialog;
      
                  // If you will not use this method url links are opeen in new brower
                  // not in webview
                  public boolean shouldOverrideUrlLoading(WebView view, String url) {
                      view.loadUrl(url);
                      return true;
                  }
                  @SuppressWarnings("deprecation")
                  @Override
                  public void onReceivedError(WebView view, int errorCode, String description, final String failingUrl) {
                      web.loadUrl("about:blank");
      
      
                  }
      
                  // Show loader on url load
                  public void onLoadResource(WebView view, String url) {
                     /* if (progressDialog == null) {
                          // in standard case YourActivity.this
                          if (getActivity() != null) {
                              progressDialog = new ProgressDialog(getActivity());
                              progressDialog.setMessage("Loading...");
                              progressDialog.show();
                          }
      
                      }*/
      
                  }
      
                  public void onPageFinished(WebView view, String url) {
                      try {
                          setProgressBar(false);
                      } catch (Exception e) {
      
                      }
                  }
      
              });
      
      
              // Load url in webview
              web.loadUrl(url);
      
          }
      

      【讨论】:

      • 拉胡尔您好,感谢您的回答。你是对的,使用 WebView 是可能的。我只是想展示另一种/新方式如何在 android 应用程序中显示 pdf 文件。
      • @StefanLindner 根据这篇在 SO stackoverflow.com/questions/2456344/… 的帖子,引入了一个新的 PdfRenderer 类 API 级别 21(棒棒糖)
      • 是的,你是对的,我什至在我的 PDFPagerAdapter 类(以及库的解码器类)中使用它。问题是,没有缩放或任何实现。上面的解决方案甚至对 pdf 图像进行了二次采样,因此您不会遇到任何内存问题。
      • okk 那么你可以使用 webview 或使用一些库。如果我的回答在一定程度上对您有所帮助,我能否获得支持,以便对其他人有所帮助
      猜你喜欢
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 2014-09-23
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      相关资源
      最近更新 更多