新版超简单的PDF阅读器

原文地址:http://blog.csdn.net/BingHongChaZuoAn/article/details/52213611

本PDF阅读器的开发是基于android23版本的,其他版本暂时没有做适配(因为google旧版没提供API,需要借助阿帕奇或者其他的API),本篇代码不超过320行,不错吧。支持pdf的页数,下一页,上一页,跳转到某一页。然后就是pdf页面的缩放和平移。

别的不多说了,直接贴代码吧(代码不够精简,需要优化下,不过功能可以):

public class PdfActivity extends Activity implements View.OnClickListener, View.OnTouchListener {

    private TextView totalPageTV;
    private EditText targetPageET;
    private TextView startToScanTV;
    private TextView nextPageTV;
    private TextView prePageTV;
    private ImageView pdfImg;
    private int currentPage = 0;
    private int totalPage = 0;
    private PdfRenderer renderer;
    private ParcelFileDescriptor parcelFileDescriptor;

    private String filePath = "123.pdf";
    private int fileType = ASSETS_FILE;

    public static final String FILE_PATH_KEY = "file_path";
    public static final String FILE_TYPE_KEY = "file_type";

    public static final int ASSETS_FILE = 0;//assets文件
    public static final int CUSTOM_FILE = 1;//普通文件

    private float scale = 1.0f;


    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();

    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;

    // 第一个按下的手指的点
    private PointF startPoint = new PointF();
    // 两个按下的手指的触摸点的中点
    private PointF midPoint = new PointF();
    // 初始的两个手指按下的触摸点的距离
    private float oriDis = 1f;

    /**
     * 最大屏幕触点数量
     */
    private final int MAX_TOUCH_POINT = 3;
    private Bitmap bitmap;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            filePath = bundle.getString(FILE_PATH_KEY, "abc.pdf");
            fileType = bundle.getInt(FILE_TYPE_KEY, ASSETS_FILE);
        }

        setContentView(R.layout.pdf_layout);
        initViews();
        ititPDF();

    }

    private void ititPDF() {

        try {

            File file = null;

            if (fileType == CUSTOM_FILE) {
                file = new File(filePath);
            } else if (fileType == ASSETS_FILE) {
                file = FileUtil.fileFromAsset(this, filePath);
            }

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

            renderer = new PdfRenderer(parcelFileDescriptor);
            totalPage = renderer.getPageCount() - 1;

            totalPageTV.setText(String.valueOf(totalPage + 1));

            showPdf();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void initViews() {
        totalPageTV = (TextView) findViewById(R.id.total_num_tv);
        targetPageET = (EditText) findViewById(R.id.target_page_tv);
        startToScanTV = (TextView) findViewById(R.id.start_to_scan_tv);
        nextPageTV = (TextView) findViewById(R.id.next_page_tv);
        prePageTV = (TextView) findViewById(R.id.pre_page_tv);
        pdfImg = (ImageView) findViewById(R.id.pdf_img);

        startToScanTV.setOnClickListener(this);
        nextPageTV.setOnClickListener(this);
        prePageTV.setOnClickListener(this);
        pdfImg.setOnTouchListener(this);


    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_to_scan_tv:
                toTargetPage();
                break;
            case R.id.pre_page_tv:
                lastPage();
                break;
            case R.id.next_page_tv:
                nextPage();
                break;
        }
    }

    private void toTargetPage() {
        String target = targetPageET.getText().toString();
        int targetPage = Integer.valueOf(target);
        if (targetPage <= 0 || targetPage > totalPage) {
            Toast.makeText(PdfActivity.this, "您选的页面超出了范围,请重新选择吧!", Toast.LENGTH_SHORT).show();
        } else {
            currentPage = targetPage;
            showPdf();
        }
    }

    private void nextPage() {
        if (currentPage >= totalPage) {
            Toast.makeText(PdfActivity.this, "没有下一页了哦!", Toast.LENGTH_SHORT).show();
        } else {
            currentPage++;
            showPdf();

        }

    }

    private void lastPage() {
        if (currentPage <= 0) {
            Toast.makeText(PdfActivity.this, "上一页不存在啊!", Toast.LENGTH_SHORT).show();
        } else {
            currentPage--;
            showPdf();
        }
    }

    private void showPdf() {

        targetPageET.setText(String.valueOf(currentPage));

        PdfRenderer.Page page = renderer.openPage(currentPage);

        int height = page.getHeight();
        int width = page.getWidth();

        Matrix matrix = new Matrix();
        int windowWidth = getResources().getDisplayMetrics().widthPixels;
        int windowheight = getResources().getDisplayMetrics().heightPixels;

        float scaleX = (float) ((scale * windowWidth) / width);
        float scaleY = (float) ((scale * windowheight) / height);
        matrix.setScale(scaleX, scaleY);


        if (bitmap != null) {
            bitmap.recycle();
        }

        bitmap = Bitmap.createBitmap(windowWidth, windowheight, Bitmap.Config.ARGB_4444);

        Rect rect = new Rect(0, 0, windowWidth, windowheight);
        page.render(bitmap, rect, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);

        pdfImg.setImageBitmap(bitmap);

        if (page != null) {
            page.close();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (bitmap != null) {
            bitmap.recycle();
        }

        if (renderer != null) {
            renderer.close();
        }

        if (parcelFileDescriptor != null) {
            try {
                parcelFileDescriptor.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        ImageView view = (ImageView) v;

        // 进行与操作是为了判断多点触摸
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                // 第一个手指按下事件
                matrix.set(view.getImageMatrix());
                savedMatrix.set(matrix);
                startPoint.set(event.getX(), event.getY());
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                // 第二个手指按下事件
                oriDis = distance(event);
                if (oriDis > 10f) {
                    savedMatrix.set(matrix);
                    midPoint = middle(event);
                    mode = ZOOM;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                // 手指放开事件
                mode = NONE;
                break;
            case MotionEvent.ACTION_MOVE:
                // 手指滑动事件
                if (mode == DRAG) {
                    // 是一个手指拖动
                    matrix.set(savedMatrix);

                    matrix.postTranslate(event.getX() - startPoint.x, event.getY()
                            - startPoint.y);
                } else if (mode == ZOOM) {
                    // 两个手指滑动
                    float newDist = distance(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oriDis;
                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }
                }
                break;
        }

        // 设置ImageView的Matrix
        view.setImageMatrix(matrix);
        return true;
    }

    // 计算两个触摸点之间的距离
    private float distance(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 计算两个触摸点的中点
    private PointF middle(MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        return new PointF(x / 2, y / 2);
    }


}

FileUtil里面就这两个方法,其他的就不贴了,太长,也和本文没啥关系

public static File fileFromAsset(Context context, String assetName) throws IOException {
        File outFile = new File(context.getCacheDir(), assetName);
        copy(context.getAssets().open(assetName), outFile);

        return outFile;
    }

    public static void copy(InputStream inputStream, File output) throws IOException {
        FileOutputStream outputStream = null;

        try {
            outputStream = new FileOutputStream(output);
            boolean read = false;
            byte[] bytes = new byte[1024];

            int read1;
            while ((read1 = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read1);
            }
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }

            }

        }

    }

xml文件:

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

    <ImageView
        android:id="@+id/pdf_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix"
        android:layout_weight="1" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="17dp"
            android:padding="5dp"
            android:text="共"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/total_num_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="12"
            android:textSize="12sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="页"
            android:textSize="12sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:padding="5dp"
            android:text="第"
            android:textSize="12sp" />

        <EditText
            android:id="@+id/target_page_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="number"
            android:padding="5dp"
            android:text="0"
            android:textSize="12sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="页"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/start_to_scan_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="GO"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/pre_page_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:padding="5dp"
            android:text="上一页"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/next_page_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:padding="5dp"
            android:text="下一页"
            android:textSize="12sp" />

    </LinearLayout>

</LinearLayout>

o了,就这么多,一个简单的pdf阅读器就完成了,哈哈,想进一步增加功能的话就优化修改并扩展一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值