一,简介

pdf文件在android sdk-21 开始就出现了PdfRender,Android Sdk-27就可以实现渲染了。

二,工作原理

获取文件标识符 --- 初始化定义PdfRender --- 获取当前页--- 生成bitmap -- ImgView展现

三,这里我使用的工具

ViewPager+PhotoView + Fragment

PhotoView --- 使得图片可放大,缩小

ViewPager --- 使得Fragment可以滑动

Fragment  --- 使得生成的bitmap图再Fragment上更换呈现

四,布局

主布局:activity_view_pager.xml

次布局:fragment_picture_slide.xml

实现函数

public class ViewPagerActivity extends AppCompatActivity {

//渲染pdf

private static PdfRenderer mPdfRenderer;

/**

* pdf文件(此文件放在asset文件夹内)

*/

private static final String FILENAME = "sample.pdf";

/**

* pdf文件描述符

*/

private static ParcelFileDescriptor mFileDescriptor;

/**

* 屏幕上当前显示的页面

*/

private static PdfRenderer.Page mCurrentPage;

/**

* 总页数

*/

private int countnum;

private ViewPager viewPager;

private TextView tv_indicator;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_view_pager);

try {

openRenderer(this);

} catch (IOException e) {

e.printStackTrace();

Toast.makeText(this, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();

}

countnum = mPdfRenderer.getPageCount();

viewPager = (ViewPager) findViewById(R.id.viewpager);

tv_indicator = (TextView) findViewById(R.id.tv_indicator);

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

tv_indicator.setText(String.valueOf(position+1)+"/"+countnum);//在当前页面滑动至其他页面后,获取position值

}

@Override

public void onPageSelected(int position) {

}

@Override

public void onPageScrollStateChanged(int state) {

}

});

viewPager.setAdapter(new PictureSlidePagerAdapter(getSupportFragmentManager()));

}

/**

* 适配器

*/

private class PictureSlidePagerAdapter extends FragmentStatePagerAdapter {

public PictureSlidePagerAdapter(FragmentManager fm) {

super(fm);

}

@Override

public Fragment getItem(int position) {

return MyFragment.newInstance(position);//返回展示不同bitmap图片的MyFragment

}

@Override

public int getCount() {

return countnum;//指定ViewPager的总页数

}

}

public static class MyFragment extends Fragment{

private int index ;

private Bitmap bitmap;

private PhotoViewAttacher mAttacher;

private ImageView imageView;

public static MyFragment newInstance(int index ) {

//防止图片混乱,使用Bundle传值给Oncreate

MyFragment f = new MyFragment();

Bundle args = new Bundle();

args.putInt("index", index);

f.setArguments(args);

return f; //获得一个包含图片位置的MyFragment的实例

}

@Override

public void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

index = getArguments() != null ? getArguments().getInt("index") : 0;

bitmap = showPage(index);

}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View v=inflater.inflate(R.layout.fragment_picture_slide,container,false);

imageView= (ImageView) v.findViewById(R.id.iv_main_pic);

mAttacher = new PhotoViewAttacher(imageView);//使用PhotoViewAttacher为图片添加支持缩放、平移的属性

imageView.setImageBitmap(bitmap);

mAttacher.update();//调用PhotoViewAttacher的update()方法,使图片重新适配布局

return v;

}

}

/**

* 打开源文件

*/

private void openRenderer(Context context) throws IOException {

// 在目录中读取PDF。

File file = new File(context.getCacheDir(), FILENAME);

if (!file.exists()) {

InputStream asset = context.getAssets().open(FILENAME);

FileOutputStream output = new FileOutputStream(file);

final byte[] buffer = new byte[1024];

int size;

while ((size = asset.read(buffer)) != -1) {

output.write(buffer, 0, size);

}

asset.close();

output.close();

}

mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);

// 这是我们用来渲染PDF的PdfRenderer。

if (mFileDescriptor != null) {

mPdfRenderer = new PdfRenderer(mFileDescriptor);

}

}

/**

* 显示指定的PDF页面到屏幕。

*

* @param index The page index.

*/

private static Bitmap showPage(int index) {

if (mPdfRenderer.getPageCount() <= index) {

return null;

}

// 在打开另一个页面之前,请确保关闭当前页面。

if (null != mCurrentPage) {

mCurrentPage.close();

}

//使用“OpenPage”打开PDF中的特定页面。

mCurrentPage = mPdfRenderer.openPage(index);

// Important: the destination bitmap must be ARGB (not RGB).

Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),

Bitmap.Config.ARGB_8888);

// 这里,我们将页面渲染到位图上。

// 要渲染页面的一部分,使用第二个和第三个参数。传递空值以获得默认结果。

// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.

mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);

// 我们准备向用户显示bitmap

return bitmap;

}

@Override

protected void onStop() {

try {

closeRenderer();

} catch (IOException e) {

e.printStackTrace();

}

super.onStop();

}

/**

* 关闭相关的资源。

*

* @throws java.io.IOException When the PDF file cannot be closed.

*/

private void closeRenderer() throws IOException {

if (null != mCurrentPage) {

mCurrentPage.close();

}

mPdfRenderer.close();

mFileDescriptor.close();

}

}

注意:导入PhotoView包

allprojects {

repositories {

maven { url "https://jitpack.io" }

}

}

dependencies {

implementation 'com.github.chrisbanes:PhotoView:2.0.0'

}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐