Android 简单实现Pdf

一,简介
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"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000">
    <TextView
        android:id="@+id/tv_indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textSize="30sp"
        android:textColor="#ffffff"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tv_indicator"
        />
</RelativeLayout>

次布局:fragment_picture_slide.xml

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

    <ImageView
        android:id="@+id/iv_main_pic"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@android:color/white"
        android:scaleType="fitCenter"
        android:contentDescription="@null"/>

</LinearLayout>

实现函数

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);//<span style="white-space: pre;">在当前页面滑动至其他页面后,获取position值</span>

            }

            @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'
}

猜你喜欢

转载自blog.csdn.net/qwer492915298/article/details/88534262