Android(安卓)简单实现Pdf
16lz
2021-01-26
一,简介
pdf文件在android sdk-21 开始就出现了PdfRender,Android Sdk-27就可以实现渲染了。
二,工作原理
获取文件标识符 --- 初始化定义PdfRender --- 获取当前页--- 生成bitmap -- ImgView展现
三,这里我使用的工具
ViewPager+PhotoView + Fragment
PhotoView --- 使得图片可放大,缩小
ViewPager --- 使得Fragment可以滑动
Fragment --- 使得生成的bitmap图再Fragment上更换呈现
四,布局
主布局:activity_view_pager.xml
<?xml version="1.0" encoding="utf-8"?>
次布局:fragment_picture_slide.xml
<?xml version="1.0" encoding="utf-8"?>
实现函数
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'}
更多相关文章
- Android的图片叠加
- Android(安卓)控件之ImageSwitcher图片切换器
- 如何将图片压缩至固定大小以下
- android实现两个页面跳转
- varnish 配置使用 Chrome,iphone,android 请求响应各自的页面
- [置顶] 学习链接
- Android(安卓)Tthread 建立线程使用方法
- Android(安卓)解决异步任务下载图片错位问题
- Android(安卓)RecyclerView使用 及 滑动时加载图片优化方案