Java 如何实现PdfRenderer缩放和滚动支持?
我正在尝试使用PdfRenderer,要求它具有缩放和滚动功能,但在Android PdfRenderer中不提供任何缩放和滚动支持,只有页面导航支持 但我想缩放和滚动支持可以实现,因为PdfRenderer使用位图使用imageview显示内容 如何使用Google PdfRenderer实现缩放和滚动支持 样品Java 如何实现PdfRenderer缩放和滚动支持?,java,android,pdfrenderer,Java,Android,Pdfrenderer,我正在尝试使用PdfRenderer,要求它具有缩放和滚动功能,但在Android PdfRenderer中不提供任何缩放和滚动支持,只有页面导航支持 但我想缩放和滚动支持可以实现,因为PdfRenderer使用位图使用imageview显示内容 如何使用Google PdfRenderer实现缩放和滚动支持 样品 PS:我使用的是谷歌提供的PdfRenderer示例,我在面对这种情况时使用的解决方案是: 在ImageView中加载PDFRender页面 将我的ImageView放在Scrol
PS:我使用的是谷歌提供的PdfRenderer示例,我在面对这种情况时使用的解决方案是:
- 在ImageView中加载PDFRender页面
- 将我的ImageView放在ScrollView(tadam scroll managed)中,并将此ScrollView放在FrameLayout中
- 添加两个按钮(滚动视图外部)以管理放大和缩小(每个按钮都会触发my ImageView上的缩放动画)。您也可以使用手势检测器来管理它,但在这样做时,我很难处理滚动行为
- 添加两个按钮以管理页面更改(仍在ScrollView之外)
- 为了获得更好的效果,我在按钮上添加了FadeIn/FadeOut动画,在OnTouchEvents上触发FadeIn(如果没有播放动画),并在FadeIn动画结束时触发FadeOut
私有按钮\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);
mCurrentPage.getWidth()
返回Postscript点的宽度,其中每个pt
为1/72英寸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"
/>