Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现PdfRenderer缩放和滚动支持?_Java_Android_Pdfrenderer - Fatal编程技术网

Java 如何实现PdfRenderer缩放和滚动支持?

Java 如何实现PdfRenderer缩放和滚动支持?,java,android,pdfrenderer,Java,Android,Pdfrenderer,我正在尝试使用PdfRenderer,要求它具有缩放和滚动功能,但在Android PdfRenderer中不提供任何缩放和滚动支持,只有页面导航支持 但我想缩放和滚动支持可以实现,因为PdfRenderer使用位图使用imageview显示内容 如何使用Google PdfRenderer实现缩放和滚动支持 样品 PS:我使用的是谷歌提供的PdfRenderer示例,我在面对这种情况时使用的解决方案是: 在ImageView中加载PDFRender页面 将我的ImageView放在Scrol

我正在尝试使用PdfRenderer,要求它具有缩放和滚动功能,但在Android PdfRenderer中不提供任何缩放和滚动支持,只有页面导航支持

但我想缩放和滚动支持可以实现,因为PdfRenderer使用位图使用imageview显示内容

如何使用Google PdfRenderer实现缩放和滚动支持 样品


PS:我使用的是谷歌提供的PdfRenderer示例,

我在面对这种情况时使用的解决方案是:

  • 在ImageView中加载PDFRender页面

  • 将我的ImageView放在ScrollView(tadam scroll managed)中,并将此ScrollView放在FrameLayout中

  • 添加两个按钮(滚动视图外部)以管理放大和缩小(每个按钮都会触发my ImageView上的缩放动画)。您也可以使用手势检测器来管理它,但在这样做时,我很难处理滚动行为

  • 添加两个按钮以管理页面更改(仍在ScrollView之外)

  • 为了获得更好的效果,我在按钮上添加了FadeIn/FadeOut动画,在OnTouchEvents上触发FadeIn(如果没有播放动画),并在FadeIn动画结束时触发FadeOut
希望我能帮助你,如果你需要更详细的信息,请告诉我,但是你现在应该知道从哪里开始

这是一个代码示例(不包括页面导航等,但只包括缩放行为和滚动,其余部分在您链接的谷歌代码示例中) 代码: C#(但很容易转换成Java)

私有按钮\u缩放按钮;
专用按钮_zoomOutButton;
私有图像视图_pdfViewContainer;
私人浮动_currentZoomLevel;
私人浮动(zoomFactor);;
私有浮动_maxZoomLevel;
私人浮动_minZoomLevel;
private void Init(View-View)//此方法的内容必须放在您的OnViewCreated方法中,这里的视图是您将在xml中找到的frameLayout
{
_zoomInButton=view.FindViewById(Resource.Id.PdfZoomInButton);
_zoomOutButton=view.FindViewById(Resource.Id.PdfZoomOutButton);
_pdfViewContainer=view.findviewbyd(Resource.Id.pdfViewContainer);
_zoomInButton.Click+=delegate{ZoomIn();};//对于您(在Java中),这必须看起来像setOnClickListener(这个);在onClick metghod中,您只需添加一个包含ZoomIn()调用的R.id.PdfZoomInButton的案例;
_点击+=委托{ZoomOut();};
_minZoomLevel=0.9f;
_maxZoomLevel=1.2f;
_zoomFactor=0.1f;
}
私有void ZoomIn()
{
如果(_currentZoomLevel+_zoomFactor<_maxZoomLevel)
{
ScaleAnimation scale=新缩放图像(_currentZoomLevel,_currentZoomLevel+_zoomFactor,_currentZoomLevel,_currentZoomLevel+_zoomFactor,Dimension.RelativeToSelf,0.5f,Dimension.RelativeToSelf,0.5f);
标度:持续时间=50;
scale.FillAfter=真;
_pdfViewContainer.StartAnimation(比例);
_currentZoomLevel+=\u zoomFactor;
}
}
私有空间ZoomOut()
{
如果(\u currentZoomLevel-\u zoomFactor>\u minZoomLevel)
{
ScaleAnimation scale=新的缩放动画(_currentZoomLevel、_currentZoomLevel-_zoomFactor、_currentZoomLevel、_currentZoomLevel-_zoomFactor、维度.RelativeToSelf、0.5f、维度.RelativeToSelf、0.5f);
标度:持续时间=50;
scale.FillAfter=真;
_pdfViewContainer.StartAnimation(比例);
_currentZoomLevel-=\u zoomFactor;
}
}
XMl



有了这一点,花点时间去理解它,再稍加努力,你就应该能够得到想要的结果。祝您愉快

我使用了@yan yankelevich的思想,并用Java编写了代码。找到合适的缩放和相应的位图大小值是一个很大的问题。不要忘记PdfRenderer只在API 21+上工作

带有PDF位图的片段
Fragment\u PDF\u renderer.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical"
    tools:context=".PdfRendererFragment">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@android:color/white"
                android:contentDescription="@null" />
        </HorizontalScrollView>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/from_divider_gray"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <Button
            android:id="@+id/previous"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/previous_page"
            android:textSize="13sp" />

        <Button
            android:id="@+id/next"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/next_page"
            android:textSize="13sp" />

        <ImageButton
            android:id="@+id/zoomout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="0dp"
            android:padding="8dp"
            android:src="@drawable/ic_zoom_out_black_36dp" />

        <ImageButton
            android:id="@+id/zoomin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="0dp"
            android:padding="8dp"
            android:src="@drawable/ic_zoom_in_black_36dp" />
    </LinearLayout>

</LinearLayout>
请注意,缩放级别取决于屏幕密度,但位图的宽度和高度(以像素为单位)仅取决于缩放级别。此外,您需要调整大小,以便在默认缩放时(对我来说,它是pdf全屏渲染的,值为12),您的pdf位图不会比视图中所需的多,也不会少

int newWidth = (int) (getResources().getDisplayMetrics().widthPixels * mCurrentPage.getWidth() / 72 * currentZoomLevel / 40);
int newHeight = (int) (getResources().getDisplayMetrics().heightPixels * mCurrentPage.getHeight() / 72 * currentZoomLevel / 64);
Bitmap bitmap = Bitmap.createBitmap(
                newWidth,
                newHeight,
                Bitmap.Config.ARGB_8888);
  • 我发现zoom 12适合我的屏幕,40和64是使位图大小合适的系数
  • mCurrentPage.getWidth()
    返回Postscript点的宽度,其中每个
    pt
    为1/72英寸
  • 72(DPI)是默认的PDF分辨率

  • PS.如果您需要同时进行垂直和水平滚动

    从这个解决方案开始:我找到了一个避免初始缩放系数和其他固定系数的好方法,只更改了这个方法:

    private void showPage(int index) {
    
        if (mPdfRenderer.getPageCount() <= index) {
            return;
        }
        if (null != mCurrentPage) {
            mCurrentPage.close();
        }
        mCurrentPage = mPdfRenderer.openPage(index);
    
        int newWidth = (int) (mVerticalScrollView.getWidth() * 
        currentZoomLevel);
        int newHeight = (int) (newWidth * 
        ((float)mCurrentPage.getHeight()/(float)mCurrentPage.getWidth()));
    
        Bitmap bitmap = Bitmap.createBitmap(
            newWidth,
            newHeight,
            Bitmap.Config.ARGB_8888);
    
       mCurrentPage.render(bitmap, null, null, 
       PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
       mImageView.setImageBitmap(bitmap);
    
       updateUi();
    
    private void showPage(int索引){
    
    如果(mPdfRenderer.getPageCount()我在这里找到了一个更好的答案:由Commonware链接:。因此,根据soshial的答案,您可以使用收缩缩放,并且可以去掉缩放按钮和常量:

    import com.davemorrissey.labs.subscaleview.ImageSource;
    import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
    

    在xml中,而不是在ImageView中:

        <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
            android:id="@+id/report_viewer_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
    
    
    
    谢谢你的回答。你能发布你的示例代码吗?完成了,但如果你只是复制粘贴它就不行了,因为它是在XamarinC#(但很容易翻译)我知道这是一个老问题,但根本不需要矩阵和dpi。你可以做一些像int newWidth=(int)(currentPage.getWidth()*currentZoomLevel/6)这样的事情;int newHeight=(int)(currentPage.getHeight()*currentZoomLevel/6);Bitmap Bitmap=Bitmap.createBitmap(newWidth,newHeight,Bitmap.Config.ARGB_8888);currentPage.render(Bitmap,null,null,pdfrender.Page.render模式_用于显示);
    private void showPage(int index) {
    
        if (mPdfRenderer.getPageCount() <= index) {
            return;
        }
        if (null != mCurrentPage) {
            mCurrentPage.close();
        }
        mCurrentPage = mPdfRenderer.openPage(index);
    
        int newWidth = (int) (mVerticalScrollView.getWidth() * 
        currentZoomLevel);
        int newHeight = (int) (newWidth * 
        ((float)mCurrentPage.getHeight()/(float)mCurrentPage.getWidth()));
    
        Bitmap bitmap = Bitmap.createBitmap(
            newWidth,
            newHeight,
            Bitmap.Config.ARGB_8888);
    
       mCurrentPage.render(bitmap, null, null, 
       PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
       mImageView.setImageBitmap(bitmap);
    
       updateUi();
    
    import com.davemorrissey.labs.subscaleview.ImageSource;
    import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
    
    private void showPage(int index) {
        if (mPdfRenderer.getPageCount() <= index) {
            return;
        }
        // Make sure to close the current page before opening another one.
        if (null != mCurrentPage) {
            mCurrentPage.close();
        }
        // Use `openPage` to open a specific page in PDF.
        mCurrentPage = mPdfRenderer.openPage(index);
        if(mBitmap==null) {
            // Important: the destination bitmap must be ARGB (not RGB).
            int newWidth = (int) (getResources().getDisplayMetrics().densityDpi * mCurrentPage.getWidth() / 72);
            int newHeight = (int) (getResources().getDisplayMetrics().densityDpi * mCurrentPage.getHeight() / 72);
            mBitmap = Bitmap.createBitmap(
                    newWidth,
                    newHeight,
                    Bitmap.Config.ARGB_8888);
        }
        mBitmap.eraseColor(0xFFFFFFFF);
        mCurrentPage.render(mBitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
        // We are ready to show the Bitmap to user.
        mSubsamplingImageView.resetScaleAndCenter();
        mSubsamplingImageView.setImage(ImageSource.cachedBitmap(mBitmap));
        updateUi();
    }
    
    /**
     * Closes the {@link android.graphics.pdf.PdfRenderer} and related resources.
     *
     * @throws java.io.IOException When the PDF file cannot be closed.
     */
    private void closeRenderer() throws IOException {
        if (null != mCurrentPage) {
            mCurrentPage.close();
            mCurrentPage = null;
        }
        if (null != mPdfRenderer) {
            mPdfRenderer.close();
        }
        if (null != mFileDescriptor) {
            mFileDescriptor.close();
        }
        if(mBitmap!=null)
        {
            mBitmap.recycle();
            mBitmap = null;
        }
    }
    
        <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
            android:id="@+id/report_viewer_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />