andorid实现pdf批注、笔记demo

Andorid实现pdf批注、笔记demo

1、兴建andorid项目

andorid实现pdf批注、笔记demo_第1张图片

2、导入pdf包

implementation ‘com.lonelypluto:pdf-viewer:1.0.5’
andorid实现pdf批注、笔记demo_第2张图片

1、创建页面和java类

1.1创建OutlineAdapter

package com.example.myapplication.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.artifex.mupdfdemo.OutlineItem;
import com.example.myapplication.R;

/**
 * @Description: 文件目录adapter
 * @author: ZhangYW
 * @time: 2019/1/22 11:17
 */
public class OutlineAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private OutlineItem mList[];

    public OutlineAdapter(Context context, OutlineItem mList[]){
        this.mContext = context;
        this.mList = mList;

    }
    /**
     * 渲染具体的ViewHolder
     * @param parent ViewHolder的容器
     * @param viewType 一个标志,我们根据该标志可以实现渲染不同类型的ViewHolder
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.outline_item,parent,false);
        return new OutlineViewHolder(itemView);
    }
    /**
     * 绑定ViewHolder的数据。
     * @param holder
     * @param position 数据源list的下标
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        OutlineItem bean = mList[position];
        if (null == bean)
            return;
        OutlineViewHolder viewHolder = (OutlineViewHolder) holder;

        int level = bean.level;
        if (level > 8) level = 8;
        String space = "";
        for (int i=0; i

1.2创建OutlineAdapter的outline_item.xml页面




	

	

    


1.3创建OnRecyclerItemClickListener

package com.example.myapplication.widget;

import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * RecyclerView监听事件
 */

public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private GestureDetectorCompat mGestureDetector;
    private RecyclerView recyclerView;

    public OnRecyclerItemClickListener(RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
        mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener());
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    }

    private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                onItemClick(vh);
            }
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                onItemLongClick(vh);
            }
        }
    }

    public abstract void onItemClick(RecyclerView.ViewHolder vh);

    public abstract void onItemLongClick(RecyclerView.ViewHolder vh);
}

1.4创建OutlineActivity

package com.example.myapplication.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.artifex.mupdfdemo.OutlineActivityData;
import com.artifex.mupdfdemo.OutlineItem;
import com.example.myapplication.R;
import com.example.myapplication.adapter.OutlineAdapter;
import com.example.myapplication.widget.OnRecyclerItemClickListener;

/**
 * @Description: 目录
 * @author: ZhangYW
 * @time: 2019/3/8 10:29
 */
public class OutlineActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private OutlineAdapter adapter;
    private OutlineItem mItems[];
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_outline);

        initData();
        initView();
        setListener();
    }

    /**
     * 初始化数据
     */
    private void initData(){
        mItems = OutlineActivityData.get().items;
    }

    /**
     * 初始化布局
     */
    private void initView(){
        adapter = new OutlineAdapter(this,mItems);
        recyclerView = (RecyclerView)findViewById(R.id.outline_rv);
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);//HORIZONTAL 水平
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
    }

    /**
     * 设置点击事件
     */
    private void setListener(){
        recyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(recyclerView) {
            @Override
            public void onItemClick(RecyclerView.ViewHolder vh) {
                OutlineActivityData.get().position = vh.getLayoutPosition();
                setResult(mItems[vh.getLayoutPosition()].page);
                finish();
            }

            @Override
            public void onItemLongClick(RecyclerView.ViewHolder vh) {

            }
        });
    }
}

1.5创建OutlineActivity的activity_outline.xml页面




    


1.6创建AllPDFActivity

package com.example.myapplication.activity;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewAnimator;

import com.artifex.mupdfdemo.Annotation;
import com.artifex.mupdfdemo.Hit;
import com.artifex.mupdfdemo.MuPDFAlert;
import com.artifex.mupdfdemo.MuPDFCore;
import com.artifex.mupdfdemo.MuPDFPageAdapter;
import com.artifex.mupdfdemo.MuPDFReaderView;
import com.artifex.mupdfdemo.MuPDFReaderViewListener;
import com.artifex.mupdfdemo.MuPDFView;
import com.artifex.mupdfdemo.OutlineActivityData;
import com.artifex.mupdfdemo.OutlineItem;
import com.artifex.mupdfdemo.ReaderView;
import com.artifex.mupdfdemo.SavePdf;
import com.artifex.mupdfdemo.SearchTask;
import com.artifex.mupdfdemo.SearchTaskResult;
import com.artifex.mupdfdemo.widget.VDHDeepLayout;
import com.example.myapplication.R;
import com.lonelypluto.pdflibrary.utils.SharedPreferencesUtil;

import java.util.concurrent.Executor;

public class AllPDFActivity extends AppCompatActivity {
    private static final String TAG = AllPDFActivity.class.getSimpleName();
    private final int OUTLINE_REQUEST = 0;
    private String filePath = Environment.getExternalStorageDirectory() + "/pdf_t1.pdf"; // 文件路径
//    private String filePath = Environment.getExternalStorageDirectory() + "/t"; // 文件路径
    private String fileName;// 文件名

    private AlertDialog.Builder mAlertBuilder;
    static private AlertDialog.Builder gAlertBuilder;

    private MuPDFCore muPDFCore;// 加载mupdf.so文件

    private MuPDFReaderView muPDFReaderView;// 显示pdf的view

    private boolean mAlertsActive = false;
    private AsyncTask mAlertTask;
    private AlertDialog mAlertDialog;

    // tools
    private ViewAnimator mTopBarSwitcher;// 工具栏动画
    private ImageButton mLinkButton;// 超链接
    private ImageButton mOutlineButton;// 目录
    private ImageButton mSearchButton;// 搜索
    private ImageButton mAnnotButton;// 注释
    // tools 搜索框
    private EditText mSearchText;// 搜索内容输入框
    private ImageButton mSearchBack;// 搜索内容上一个
    private ImageButton mSearchFwd;// 搜索内容下一个
    // tools 注释类型
    private TextView mAnnotTypeText;// 注释类型
    // tools 底部布局
    private TextView mPageNumberView;// 页数
    private SeekBar mPageSlider;// 底部拖动条

    private int mPageSliderRes;// 拖动条的个数
    private boolean mButtonsVisible;// 是否显示工具栏
    private TopBarMode mTopBarMode = TopBarMode.Main;// 工具栏类型
    private AcceptMode mAcceptMode;// 工具栏注释类型

    private SearchTask mSearchTask;// 搜索线程
    private boolean mLinkHighlight = false;// 是否高亮显示


    private Button btn_change_hv;// 切换横竖显示
    private boolean ischangeHV = false;// 横竖切换
    private Button btn_linkhighlightcolor;// 设置超链接颜色
    private Button btn_searchtextcolor;// 设置搜索文字颜色
    private Button btn_paintcolor;// 设置画笔颜色
    private Button btn_paintstrokewidth;// 设置画笔粗细

    private Button btn_sign;// 电子签章
    private Button btn_save;// 保存
    private VDHDeepLayout vdhDeepLayout;
    private ImageView iv_sign;

    private ImageView iv_test;

    private SavePdfTask savePdfTask;
    /*
     * 用于存储的异步,并上传更新
     * */
    class SavePdfTask extends AsyncTask {

        SavePdf savePdf;
        public SavePdfTask(SavePdf savePdf) {
            this.savePdf = savePdf;
        }

        @Override
        protected Object doInBackground(Object[] params) {
            savePdf.addText();
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            Log.e(TAG, "存储完成");
            try {


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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_all_pdf);

        initView();
    }

    private void initView() {
        SharedPreferencesUtil.init(getApplication());

        muPDFReaderView = (MuPDFReaderView)findViewById(R.id.open_pdf_mupdfreaderview);

        initToolsView();

        mAlertBuilder  = new AlertDialog.Builder(this);
        //  keep a static copy of this that other classes can use
        gAlertBuilder = mAlertBuilder;

        String path = filePath;

        // 通过MuPDFCore打开pdf文件
        muPDFCore = openFile(path);
        // 搜索设为空
        SearchTaskResult.set(null);
        // 判断如果core为空,提示不能打开文件
        if (muPDFCore == null) {
            AlertDialog alert = mAlertBuilder.create();
            alert.setTitle(com.lonelypluto.pdflibrary.R.string.cannot_open_document);
            alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(com.lonelypluto.pdflibrary.R.string.dismiss),
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    });
            alert.setOnCancelListener(new DialogInterface.OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    finish();
                }
            });
            alert.show();
            return;
        }

        createUI();

        //切换横竖显示
        btn_change_hv = (Button)findViewById(R.id.btn_change_hv);
        btn_change_hv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ischangeHV) {
                    muPDFReaderView.setHorizontalScrolling(ischangeHV);
                    btn_change_hv.setText("横");
                    ischangeHV = false;
                } else {
                    muPDFReaderView.setHorizontalScrolling(ischangeHV);
                    btn_change_hv.setText("竖");
                    ischangeHV = true;
                }
            }
        });

        // 改变超链接颜色
        btn_linkhighlightcolor = (Button)findViewById(R.id.btn_linkhighlightcolor);
        btn_linkhighlightcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setLinkHighlightColor(ContextCompat.getColor(AllPDFActivity.this, com.lonelypluto.pdflibrary.R.color.link_bg));
            }
        });

        // 改变搜索文字颜色
        btn_searchtextcolor = (Button)findViewById(R.id.btn_searchtextcolor);
        btn_searchtextcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setSearchTextColor(ContextCompat.getColor(AllPDFActivity.this, com.lonelypluto.pdflibrary.R.color.search_bg));
            }
        });

        // 设置画笔颜色
        btn_paintcolor = (Button)findViewById(R.id.btn_set_paint_color);
        btn_paintcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int c = ContextCompat.getColor(AllPDFActivity.this, com.lonelypluto.pdflibrary.R.color.rv_item_line_bg);
                Log.e(TAG, "color = " + c);
                setColor(c);
                setInkColor(0xFF0000FF);
            }
        });

        // 设置画笔粗细
        btn_paintstrokewidth = (Button)findViewById(R.id.btn_set_paint_strokewidth);
        btn_paintstrokewidth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setPaintStrockWidth(20.0f);
            }
        });

        // 电子签章
        btn_sign = (Button)findViewById(R.id.btn_sign);
        btn_sign.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "btn_sign");
                vdhDeepLayout.setVisibility(View.VISIBLE);
            }
        });

        // 保存
        btn_save = (Button)findViewById(R.id.btn_save);
        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "btn_save");
                String in_path = filePath;
                String out_path = in_path.substring(0, in_path.length() - 4) + "_t2.pdf";
                SavePdf savePdf = new SavePdf(in_path, out_path);
                savePdf.setScale(muPDFReaderView.getCurrentScale());
                savePdf.setPageNum(muPDFReaderView.getDisplayedViewIndex() + 1);

                savePdf.setWidthScale(1.0f * muPDFReaderView.getScaleX() / muPDFReaderView.getDisplayedView().getWidth());//计算宽偏移的百分比
                savePdf.setHeightScale(1.0f * muPDFReaderView.getScaleY() / muPDFReaderView.getDisplayedView().getHeight());//计算长偏移的百分比

                Log.e(TAG, "scaleX = " + muPDFReaderView.getScaleX() + "   " + muPDFReaderView.getDisplayedView().getWidth());
                savePdf.setWH(iv_sign.getX(), iv_sign.getY());
//                savePdf.setWidthScale(0);
//                savePdf.setHeightScale(0);

                //计算分辨率密度
                DisplayMetrics metric = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(metric);

                float density = metric.density;
                savePdf.setDensity(density);

                Bitmap bitmap = getBitmap(AllPDFActivity.this, com.lonelypluto.pdflibrary.R.mipmap.ic_launcher);
                savePdf.setBitmap(bitmap);

//                Bitmap bitmap = Bitmap.createBitmap(vdhDeepLayout.getWidth(), vdhDeepLayout.getHeight(),
//                        Bitmap.Config.ARGB_8888);
//                Canvas canvas = new Canvas(bitmap);
//                vdhDeepLayout.draw(canvas);
//                savePdf.setBitmap(bitmap);

                Log.e(TAG, "iv_p = " + iv_sign.getX() + " " + iv_sign.getY());
                Log.e(TAG, "屏幕 = " + vdhDeepLayout.getWidth() + " " + vdhDeepLayout.getHeight());
                savePdfTask = new SavePdfTask(savePdf);
                savePdfTask.execute();
            }
        });

        vdhDeepLayout = (VDHDeepLayout)findViewById(R.id.VDHDeepLayout);
        iv_sign = (ImageView)findViewById(R.id.iv_sign);

        iv_test = (ImageView)findViewById(R.id.iv_test);
    }

    private static Bitmap getBitmap(Context context,int vectorDrawableId) {
        Bitmap bitmap=null;
        if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){
            Drawable vectorDrawable = context.getDrawable(vectorDrawableId);
            bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
                    vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            vectorDrawable.draw(canvas);
        }else {
            bitmap = BitmapFactory.decodeResource(context.getResources(), vectorDrawableId);
        }
        return bitmap;
    }

    public void setColor(int color) {
        int red = (color & 0xff0000) >> 16;
        int green = (color & 0x00ff00) >> 8;
        int blue = (color & 0x0000ff);
        Log.e(TAG, "r = " + red + " g = " + green + " b = " + blue);
    }

    /**
     * 初始化工具栏
     */
    private void initToolsView() {

        mTopBarSwitcher = (ViewAnimator) findViewById(R.id.switcher);
        mLinkButton = (ImageButton) findViewById(R.id.linkButton);
        mAnnotButton = (ImageButton) findViewById(R.id.reflowButton);
        mOutlineButton = (ImageButton) findViewById(R.id.outlineButton);
        mSearchButton = (ImageButton) findViewById(R.id.searchButton);

        mSearchText = (EditText) findViewById(R.id.searchText);
        mSearchBack = (ImageButton) findViewById(R.id.searchBack);
        mSearchFwd = (ImageButton) findViewById(R.id.searchForward);

        mAnnotTypeText = (TextView) findViewById(R.id.annotType);

        mPageNumberView = (TextView) findViewById(R.id.pageNumber);
        mPageSlider = (SeekBar) findViewById(R.id.pageSlider);

        mTopBarSwitcher.setVisibility(View.INVISIBLE);
        mPageNumberView.setVisibility(View.INVISIBLE);
        mPageSlider.setVisibility(View.INVISIBLE);
    }

    /**
     * 打开文件
     * @param path 文件路径
     * @return
     */
    private MuPDFCore openFile(String path) {
        int lastSlashPos = path.lastIndexOf('/');
        fileName = new String(lastSlashPos == -1
                ? path
                : path.substring(lastSlashPos + 1));
        Log.e(TAG, "filename = " + fileName);
        Log.e(TAG, "Trying to open " + path);
        try {
            muPDFCore = new MuPDFCore(this, path);
            // 新建:删除旧的目录数据
            OutlineActivityData.set(null);
        } catch (Exception e) {
            Log.e(TAG, "openFile catch:" + e.toString());
            return null;
        } catch (OutOfMemoryError e) {
            //  out of memory is not an Exception, so we catch it separately.
            Log.e(TAG, "openFile catch: OutOfMemoryError " + e.toString());
            return null;
        }
        return muPDFCore;
    }

    private void createUI() {
        if (muPDFCore == null)
            return;
        // Set up the page slider
        int smax = Math.max(muPDFCore.countPages() - 1, 1);
        mPageSliderRes = ((10 + smax - 1) / smax) * 2;

        // Now create the UI.
        // First create the document view

        muPDFReaderView.setListener(new MuPDFReaderViewListener() {
            @Override
            public void onMoveToChild(int i) {
                if (muPDFCore == null)
                    return;

                mPageNumberView.setText(String.format("%d / %d", i + 1,
                        muPDFCore.countPages()));
                mPageSlider.setMax((muPDFCore.countPages() - 1) * mPageSliderRes);
                mPageSlider.setProgress(i * mPageSliderRes);
            }

            @Override
            public void onTapMainDocArea() {
                if (!mButtonsVisible) {
                    showButtons();
                } else {
                    if (mTopBarMode == TopBarMode.Main)
                        hideButtons();
                }
            }

            @Override
            public void onDocMotion() {
                hideButtons();
            }

            @Override
            public void onHit(Hit item) {
                switch (mTopBarMode) {
                    case Annot:
                        if (item == Hit.Annotation) {
                            showButtons();
                            mTopBarMode = TopBarMode.Delete;
                            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                        }
                        break;
                    case Delete:
                        mTopBarMode = TopBarMode.Annot;
                        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                        // fall through
                    default:
                        // Not in annotation editing mode, but the pageview will
                        // still select and highlight hit annotations, so
                        // deselect just in case.
                        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
                        if (pageView != null)
                            pageView.deselectAnnotation();
                        break;
                }
            }
        });

        muPDFReaderView.setAdapter(new MuPDFPageAdapter(this, muPDFCore));
        // 设置view的背景色
        muPDFReaderView.setBackgroundColor(ContextCompat.getColor(this, com.lonelypluto.pdflibrary.R.color.muPDFReaderView_bg));

        mSearchTask = new SearchTask(this, muPDFCore) {
            @Override
            protected void onTextFound(SearchTaskResult result) {
                SearchTaskResult.set(result);
                // Ask the ReaderView to move to the resulting page
                muPDFReaderView.setDisplayedViewIndex(result.pageNumber);
                // Make the ReaderView act on the change to SearchTaskResult
                // via overridden onChildSetup method.
                muPDFReaderView.resetupChildren();
            }
        };

        mPageSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onStopTrackingTouch(SeekBar seekBar) {
                muPDFReaderView.setDisplayedViewIndex((seekBar.getProgress() + mPageSliderRes / 2) / mPageSliderRes);
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                updatePageNumView((progress + mPageSliderRes / 2) / mPageSliderRes);
            }
        });

        // Activate the search-preparing button
        mSearchButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                searchModeOn();
            }
        });


        if (muPDFCore.fileFormat().startsWith("PDF") && muPDFCore.isUnencryptedPDF() && !muPDFCore.wasOpenedFromBuffer()) {
            mAnnotButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    mTopBarMode = TopBarMode.Annot;
                    mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                }
            });
        } else {
            mAnnotButton.setVisibility(View.GONE);
        }

        // Search invoking buttons are disabled while there is no text specified
        mSearchBack.setEnabled(false);
        mSearchFwd.setEnabled(false);
        mSearchBack.setColorFilter(Color.argb(0xFF, 250, 250, 250));
        mSearchFwd.setColorFilter(Color.argb(0xFF, 250, 250, 250));

        // React to interaction with the text widget
        mSearchText.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {
                boolean haveText = s.toString().length() > 0;
                setButtonEnabled(mSearchBack, haveText);
                setButtonEnabled(mSearchFwd, haveText);

                // Remove any previous search results
                if (SearchTaskResult.get() != null && !mSearchText.getText().toString().equals(SearchTaskResult.get().txt)) {
                    SearchTaskResult.set(null);
                    muPDFReaderView.resetupChildren();
                }
            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
            }

            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
            }
        });

        //React to Done button on keyboard
        mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE)
                    search(1);
                return false;
            }
        });

        mSearchText.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER)
                    search(1);
                return false;
            }
        });

        // Activate search invoking buttons
        mSearchBack.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                search(-1);
            }
        });
        mSearchFwd.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                search(1);
            }
        });

        mLinkButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                setLinkHighlight(!mLinkHighlight);
            }
        });

        // 判断如果pdf文件有目录
        if (muPDFCore.hasOutline()) {
            // 点击目录按钮跳转到目录页
            mOutlineButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    OutlineItem outline[] = muPDFCore.getOutline();
                    if (outline != null) {
                        OutlineActivityData.get().items = outline;
                        Intent intent = new Intent(AllPDFActivity.this, OutlineActivity.class);
                        startActivityForResult(intent, OUTLINE_REQUEST);
                    }
                }
            });
        } else {
            mOutlineButton.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case OUTLINE_REQUEST:
                if (resultCode >= 0)
                    muPDFReaderView.setDisplayedViewIndex(resultCode);
                break;
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 显示工具栏
     */
    private void showButtons() {
        if (muPDFCore == null)
            return;
        if (!mButtonsVisible) {
            mButtonsVisible = true;
            // Update page number text and slider
            int index = muPDFReaderView.getDisplayedViewIndex();
            updatePageNumView(index);
            mPageSlider.setMax((muPDFCore.countPages() - 1) * mPageSliderRes);
            mPageSlider.setProgress(index * mPageSliderRes);
            if (mTopBarMode == TopBarMode.Search) {
                mSearchText.requestFocus();
                showKeyboard();
            }

            Animation anim = new TranslateAnimation(0, 0, -mTopBarSwitcher.getHeight(), 0);
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mTopBarSwitcher.setVisibility(View.VISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                }
            });
            mTopBarSwitcher.startAnimation(anim);

            anim = new TranslateAnimation(0, 0, mPageSlider.getHeight(), 0);
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mPageSlider.setVisibility(View.VISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mPageNumberView.setVisibility(View.VISIBLE);
                }
            });
            mPageSlider.startAnimation(anim);
        }
    }

    /**
     * 隐藏工具栏
     */
    private void hideButtons() {
        if (mButtonsVisible) {
            mButtonsVisible = false;
            hideKeyboard();

            Animation anim = new TranslateAnimation(0, 0, 0, -mTopBarSwitcher.getHeight());
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mTopBarSwitcher.setVisibility(View.INVISIBLE);
                }
            });
            mTopBarSwitcher.startAnimation(anim);

            anim = new TranslateAnimation(0, 0, 0, mPageSlider.getHeight());
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mPageNumberView.setVisibility(View.INVISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mPageSlider.setVisibility(View.INVISIBLE);
                }
            });
            mPageSlider.startAnimation(anim);
        }
    }

    /**
     * 更新当前是第多少页
     * @param index
     */
    private void updatePageNumView(int index) {
        if (muPDFCore == null)
            return;
        mPageNumberView.setText(String.format("%d / %d", index + 1, muPDFCore.countPages()));
    }

    /**
     * 显示键盘
     */
    private void showKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null)
            imm.showSoftInput(mSearchText, 0);
    }

    /**
     * 隐藏键盘
     */
    private void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null)
            imm.hideSoftInputFromWindow(mSearchText.getWindowToken(), 0);
    }

    /**
     * 工具栏 - 注释点击事件
     * @param v
     */
    public void OnEditAnnotButtonClick(View v) {
        mTopBarMode = TopBarMode.Main;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 复制点击事件
     * @param v
     */
    public void OnCopyTextButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.CopyText;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(getString(com.lonelypluto.pdflibrary.R.string.copy_text));
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 搜索框取消点击事件
     * @param v
     */
    public void OnCancelSearchButtonClick(View v) {
        searchModeOff();
    }

    /**
     * 工具栏 - 注释取消点击事件
     * @param v
     */
    public void OnCancelMoreButtonClick(View v) {
        mTopBarMode = TopBarMode.Main;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 开始搜索
     */
    private void searchModeOn() {
        if (mTopBarMode != TopBarMode.Search) {
            mTopBarMode = TopBarMode.Search;
            //Focus on EditTextWidget
            mSearchText.requestFocus();
            showKeyboard();
            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        }
    }

    /**
     * 取消搜索
     */
    private void searchModeOff() {
        if (mTopBarMode == TopBarMode.Search) {
            mTopBarMode = TopBarMode.Main;
            hideKeyboard();
            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
            SearchTaskResult.set(null);
            // Make the ReaderView act on the change to mSearchTaskResult
            // via overridden onChildSetup method.
            muPDFReaderView.resetupChildren();
        }
    }

    /**
     * 工具栏 - 注释 - 高亮点击事件
     * @param v
     */
    public void OnHighlightButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Highlight;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_highlight);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 底部画线点击事件
     * @param v
     */
    public void OnUnderlineButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Underline;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_underline);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 废弃线点击事件
     * @param v
     */
    public void OnStrikeOutButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.StrikeOut;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_strike_out);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 签字点击事件
     * @param v
     */
    public void OnInkButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Ink;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Drawing);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_ink);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.pdf_tools_draw_annotation));
    }

    /**
     * 工具栏 - 注释 - 删除注释点击事件
     * @param v
     */
    public void OnDeleteButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null)
            pageView.deleteSelectedAnnotation();
        mTopBarMode = TopBarMode.Annot;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 取消删除注释点击事件
     * @param v
     */
    public void OnCancelDeleteButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null)
            pageView.deselectAnnotation();
        mTopBarMode = TopBarMode.Annot;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 取消点击事件
     * @param v
     */
    public void OnCancelAcceptButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null) {
            pageView.deselectText();
            pageView.cancelDraw();
        }
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Viewing);
        switch (mAcceptMode) {
            case CopyText:
                mTopBarMode = TopBarMode.Main;
                break;
            default:
                mTopBarMode = TopBarMode.Annot;
                break;
        }
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 确定点击事件
     * @param v
     */
    public void OnAcceptButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        boolean success = false;
        switch (mAcceptMode) {
            case CopyText:
                if (pageView != null)
                    success = pageView.copySelection();
                mTopBarMode = TopBarMode.Main;
                showInfo(success ? getString(com.lonelypluto.pdflibrary.R.string.copied_to_clipboard) : getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;
            case Highlight:
                // 高亮
                if (pageView != null) {
                    success = pageView.markupSelection(Annotation.Type.HIGHLIGHT);
                }
                mTopBarMode = TopBarMode.Annot;
                if (!success) {
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                }
                break;
            case Underline:
                if (pageView != null)
                    success = pageView.markupSelection(Annotation.Type.UNDERLINE);
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;

            case StrikeOut:
                if (pageView != null)
                    success = pageView.markupSelection(Annotation.Type.STRIKEOUT);
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;

            case Ink:
                if (pageView != null)
                    success = pageView.saveDraw();
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.nothing_to_save));
                break;
        }
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Viewing);
    }

    /**
     * 设置按钮是否可点击
     * @param button
     * @param enabled
     */
    private void setButtonEnabled(ImageButton button, boolean enabled) {
        button.setEnabled(enabled);
        button.setColorFilter(enabled ? Color.argb(0xFF, 250, 250, 250) : Color.argb(0xFF, 250, 250, 250));
    }

    /**
     * 开始搜索
     * @param direction 搜索内容
     */
    private void search(int direction) {
        hideKeyboard();
        int displayPage = muPDFReaderView.getDisplayedViewIndex();
        SearchTaskResult r = SearchTaskResult.get();
        int searchPage = r != null ? r.pageNumber : -1;
        mSearchTask.go(mSearchText.getText().toString(), direction, displayPage, searchPage);
    }

    /**
     * 设置超链接高亮显示
     * @param highlight
     */
    private void setLinkHighlight(boolean highlight) {
        mLinkHighlight = highlight;
        // LINK_COLOR tint
        mLinkButton.setColorFilter(highlight ? Color.argb(0xFF, 255, 160, 0) : Color.argb(0xFF, 255, 255, 255));
        // Inform pages of the change.
        muPDFReaderView.setLinksEnabled(highlight);
    }

    /**
     * 设置超链接颜色
     * @param color 颜色值
     */
    private void setLinkHighlightColor(int color) {
        muPDFReaderView.setLinkHighlightColor(color);
    }

    /**
     * 设置搜索文字颜色
     * @param color 颜色值
     */
    private void setSearchTextColor(int color) {
        muPDFReaderView.setSearchTextColor(color);
    }

    /**
     * 设置画笔颜色
     * @param color 颜色值
     */
    private void setInkColor(int color) {
        muPDFReaderView.setInkColor(color);
    }

    /**
     * 设置画笔粗细
     * @param inkThickness 粗细值
     */
    private void setPaintStrockWidth(float inkThickness) {
        muPDFReaderView.setPaintStrockWidth(inkThickness);
    }

    /**
     * 工具栏弹出提示信息
     * @param message 提示内容
     */
    private void showInfo(String message) {

        LayoutInflater inflater = getLayoutInflater();
        View toastLayout = inflater.inflate(com.lonelypluto.pdflibrary.R.layout.toast,
                (ViewGroup) findViewById(com.lonelypluto.pdflibrary.R.id.toast_root_view));

        TextView header = (TextView) toastLayout.findViewById(com.lonelypluto.pdflibrary.R.id.toast_message);
        header.setText(message);

        Toast toast = new Toast(getApplicationContext());
        toast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.BOTTOM, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(toastLayout);
        toast.show();
    }

    /**
     * 获取静态dialog
     * @return
     */
    public static AlertDialog.Builder getAlertBuilder() {
        return gAlertBuilder;
    }

    /**
     * 创建提示等待
     */
    public void createAlertWaiter() {
        mAlertsActive = true;
        // All mupdf library calls are performed on asynchronous tasks to avoid stalling
        // the UI. Some calls can lead to javascript-invoked requests to display an
        // alert dialog and collect a reply from the user. The task has to be blocked
        // until the user's reply is received. This method creates an asynchronous task,
        // the purpose of which is to wait of these requests and produce the dialog
        // in response, while leaving the core blocked. When the dialog receives the
        // user's response, it is sent to the core via replyToAlert, unblocking it.
        // Another alert-waiting task is then created to pick up the next alert.
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
        if (mAlertDialog != null) {
            mAlertDialog.cancel();
            mAlertDialog = null;
        }
        mAlertTask = new AsyncTask() {

            @Override
            protected MuPDFAlert doInBackground(Void... arg0) {
                if (!mAlertsActive)
                    return null;

                return muPDFCore.waitForAlert();
            }

            @Override
            protected void onPostExecute(final MuPDFAlert result) {
                // core.waitForAlert may return null when shutting down
                if (result == null)
                    return;
                final MuPDFAlert.ButtonPressed pressed[] = new MuPDFAlert.ButtonPressed[3];
                for (int i = 0; i < 3; i++)
                    pressed[i] = MuPDFAlert.ButtonPressed.None;
                DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        mAlertDialog = null;
                        if (mAlertsActive) {
                            int index = 0;
                            switch (which) {
                                case AlertDialog.BUTTON1:
                                    index = 0;
                                    break;
                                case AlertDialog.BUTTON2:
                                    index = 1;
                                    break;
                                case AlertDialog.BUTTON3:
                                    index = 2;
                                    break;
                            }
                            result.buttonPressed = pressed[index];
                            // Send the user's response to the core, so that it can
                            // continue processing.
                            muPDFCore.replyToAlert(result);
                            // Create another alert-waiter to pick up the next alert.
                            createAlertWaiter();
                        }
                    }
                };
                mAlertDialog = mAlertBuilder.create();
                mAlertDialog.setTitle(result.title);
                mAlertDialog.setMessage(result.message);
                switch (result.iconType) {
                    case Error:
                        break;
                    case Warning:
                        break;
                    case Question:
                        break;
                    case Status:
                        break;
                }
                switch (result.buttonGroupType) {
                    case OkCancel:
                        mAlertDialog.setButton(AlertDialog.BUTTON2, getString(com.lonelypluto.pdflibrary.R.string.cancel), listener);
                        pressed[1] = MuPDFAlert.ButtonPressed.Cancel;
                    case Ok:
                        mAlertDialog.setButton(AlertDialog.BUTTON1, getString(com.lonelypluto.pdflibrary.R.string.okay), listener);
                        pressed[0] = MuPDFAlert.ButtonPressed.Ok;
                        break;
                    case YesNoCancel:
                        mAlertDialog.setButton(AlertDialog.BUTTON3, getString(com.lonelypluto.pdflibrary.R.string.cancel), listener);
                        pressed[2] = MuPDFAlert.ButtonPressed.Cancel;
                    case YesNo:
                        mAlertDialog.setButton(AlertDialog.BUTTON1, getString(com.lonelypluto.pdflibrary.R.string.yes), listener);
                        pressed[0] = MuPDFAlert.ButtonPressed.Yes;
                        mAlertDialog.setButton(AlertDialog.BUTTON2, getString(com.lonelypluto.pdflibrary.R.string.no), listener);
                        pressed[1] = MuPDFAlert.ButtonPressed.No;
                        break;
                }
                mAlertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    public void onCancel(DialogInterface dialog) {
                        mAlertDialog = null;
                        if (mAlertsActive) {
                            result.buttonPressed = MuPDFAlert.ButtonPressed.None;
                            muPDFCore.replyToAlert(result);
                            createAlertWaiter();
                        }
                    }
                });

                mAlertDialog.show();
            }
        };

        mAlertTask.executeOnExecutor(new ThreadPerTaskExecutor());
    }

    /**
     * 销毁提示等待
     */
    public void destroyAlertWaiter() {
        mAlertsActive = false;
        if (mAlertDialog != null) {
            mAlertDialog.cancel();
            mAlertDialog = null;
        }
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
    }

    @Override
    protected void onStart() {
        if (muPDFCore != null) {
            muPDFCore.startAlerts();
            createAlertWaiter();
        }
        super.onStart();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mSearchTask != null) {
            mSearchTask.stop();
        }

//        if (mFileName != null && mDocView != null) {
//            SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
//            SharedPreferences.Editor edit = prefs.edit();
//            edit.putInt("page" + mFileName, mDocView.getDisplayedViewIndex());
//            edit.commit();
//        }
    }

    @Override
    protected void onStop() {
        if (muPDFCore != null) {
            destroyAlertWaiter();
            muPDFCore.stopAlerts();
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        if (muPDFReaderView != null) {
            muPDFReaderView.applyToChildren(new ReaderView.ViewMapper() {
                public void applyToView(View view) {
                    ((MuPDFView) view).releaseBitmaps();
                }
            });
        }
        if (muPDFCore != null)
            muPDFCore.onDestroy();
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
        muPDFCore = null;
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (muPDFCore != null && muPDFCore.hasChanges()) {
            DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    if (which == AlertDialog.BUTTON_POSITIVE) {
                        muPDFCore.save();
                    }
                    finish();
                }
            };
            AlertDialog alert = mAlertBuilder.create();
            alert.setTitle(com.lonelypluto.pdflibrary.R.string.dialog_title);
            alert.setMessage(getString(com.lonelypluto.pdflibrary.R.string.document_has_changes_save_them));
            alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(com.lonelypluto.pdflibrary.R.string.yes), listener);
            alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(com.lonelypluto.pdflibrary.R.string.no), listener);
            alert.show();
        } else {
            finish();
        }
    }

    /**
     * 多线程类
     */
    class ThreadPerTaskExecutor implements Executor {
        public void execute(Runnable r) {
            new Thread(r).start();
        }
    }

    /**
     * 工具栏类型 Search:搜索 Annot:注释
     */
    enum TopBarMode {
        Main, Search, Annot, Delete, Accept
    }

    /**
     * 工具栏注释类型 Highlight:高亮显示 ,Underline:底部画线 ,StrikeOut:废弃线 ,Ink:签字 ,CopyText:复制文字
     */
    enum AcceptMode {
        Highlight, Underline, StrikeOut, Ink, CopyText
    }
}

1.7创建AllPDFActivity的activity_all_pdf.xml页面




    

    

    
        

1.8创建activity_all_pdf的依赖pdf_tools.xml页面





    

        
        

            

            

            

            

            

        

        
        

            

            

            

            

        

        
        

            

            

            

            

            

        

        
        

            

            

            

        

        
        

            

            

            
        
    

    
    

        

        
    


1.9创建MainBean

package com.example.myapplication.entry;

/**
 * @Description: 列表bean
 * @author: ZhangYW
 * @time: 2019/3/11 16:16
 */
public class MainBean {
    /**
     * 标题
     */
    private String title;
    /**
     * 描述
     */
    private String describe;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescribe() {
        return describe;
    }

    public void setDescribe(String describe) {
        this.describe = describe;
    }
}

1.9创建MainAdapter

package com.example.myapplication.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import com.example.myapplication.R;
import com.example.myapplication.entry.MainBean;

import java.util.List;

/**
 * @Description: 文件目录adapter
 * @author: ZhangYW
 * @time: 2019/1/22 11:17
 */
public class MainAdapter extends RecyclerView.Adapter {
    private Context mContext;
    private List mList;

    public MainAdapter(Context context, List list){
        this.mContext = context;
        this.mList = list;

    }
    /**
     * 渲染具体的ViewHolder
     * @param parent ViewHolder的容器
     * @param viewType 一个标志,我们根据该标志可以实现渲染不同类型的ViewHolder
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.main_item,parent,false);
        return new MainViewHolder(itemView);
    }
    /**
     * 绑定ViewHolder的数据。
     * @param holder
     * @param position 数据源list的下标
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        MainBean bean = mList.get(position);
        if (null == bean)
            return;
        MainViewHolder viewHolder = (MainViewHolder) holder;

        viewHolder.tv_title.setText(bean.getTitle());
        viewHolder.tv_describe.setText(bean.getDescribe());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public static class MainViewHolder extends  RecyclerView.ViewHolder{
        public TextView tv_title;
        public TextView tv_describe;

        public MainViewHolder(View itemView){
            super(itemView);
            tv_title = (TextView) itemView.findViewById(R.id.main_item_tv_title);
            tv_describe = (TextView) itemView.findViewById(R.id.main_item_tv_describe);
        }
    }

}

1.10创建MainAdapter的main_item.xml页面




	

	

    


1.11创建MainActivity

package com.example.myapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;


import com.example.myapplication.adapter.MainAdapter;
import com.example.myapplication.entry.MainBean;
import com.example.myapplication.widget.OnRecyclerItemClickListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    private final int WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 101;

    private RecyclerView recyclerView;
    private MainAdapter adapter;
    private List list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        checkPermissions();

        initData();
        initView();
        setListener();
    }

    /**
     * 初始化数据
     */
    private void initData(){
        list = new ArrayList<>();
        List list_title = Arrays.asList(getResources().getStringArray(R.array.main_title));
        List list_describe = Arrays.asList(getResources().getStringArray(R.array.main_describe));
        for (int i = 0; i < list_title.size(); i++) {
            MainBean bean = new MainBean();
            bean.setTitle(list_title.get(i));
            bean.setDescribe(list_describe.get(i));
            list.add(bean);
        }
    }

    /**
     * 初始化布局
     */
    private void initView(){
        adapter = new MainAdapter(this, list);
        recyclerView = (RecyclerView)findViewById(R.id.main_rv);
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);//HORIZONTAL 水平
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(adapter);
    }

    /**
     * 设置点击事件
     */
    private void setListener(){
        recyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(recyclerView) {
            @Override
            public void onItemClick(RecyclerView.ViewHolder vh) {
                switch (vh.getLayoutPosition()) {
                    case 0:
                        // 基础功能仅显示pdf
//                        startActivity(new Intent(MainActivity.this, BasePDFActivity.class));
                        break;
                    case 1:
                        // MuPDF已有功能
//                        startActivity(new Intent(MainActivity.this, MuPDFActivity.class));
                        break;
                    case 2:
                        // 一些主要方法的设置
                        startActivity(new Intent(MainActivity.this, MoreSetActivity.class));
                        break;
                    case 3:
                        // 电子签章
//                        startActivity(new Intent(MainActivity.this, SignActivity.class));
                        break;
                }

            }

            @Override
            public void onItemLongClick(RecyclerView.ViewHolder vh) {

            }
        });
    }

    /**
     * 权限回调
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case WRITE_EXTERNAL_STORAGE_REQUEST_CODE:
                java.util.Map perms = new HashMap<>();
                perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                for (int i = 0; i < permissions.length; i++){
                    perms.put(permissions[i], grantResults[i]);
                }
                Boolean storage = perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
                if (storage) {
                    Toast.makeText(this, "允许存储权限", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "存储权限被拒绝", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * 申请读写权限
     */
    private void checkPermissions() {
        List permissions = new ArrayList<>();

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (!permissions.isEmpty()) {
            String[] params = permissions.toArray(new String[permissions.size()]);
            ActivityCompat.requestPermissions(this, params, WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
        } else {

        }
    }
}

1.12创建MainActivity的activity_main.xml页面




    


1.13创建array.xml页面




    
        基础pdf显示
        MuPDF自带功能
        主要方法的设置
        pdf插入图片
    
    
        最基本的显示一个pdf文件 BasePDFActivity
        MuPDF自带功能 MuPDFActivity
        包括横竖滑动切换、超链接颜色、搜索颜色、画笔颜色、画笔粗细 SetVoidActivity
        类似电子签章功能 SignActivity
    

1.13创建MoreSetActivity

package com.example.myapplication.activity;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewAnimator;

import com.artifex.mupdfdemo.Annotation;
import com.artifex.mupdfdemo.Hit;
import com.artifex.mupdfdemo.MuPDFAlert;
import com.artifex.mupdfdemo.MuPDFCore;
import com.artifex.mupdfdemo.MuPDFPageAdapter;
import com.artifex.mupdfdemo.MuPDFReaderView;
import com.artifex.mupdfdemo.MuPDFReaderViewListener;
import com.artifex.mupdfdemo.MuPDFView;
import com.artifex.mupdfdemo.OutlineActivityData;
import com.artifex.mupdfdemo.OutlineItem;
import com.artifex.mupdfdemo.ReaderView;
import com.artifex.mupdfdemo.SearchTask;
import com.artifex.mupdfdemo.SearchTaskResult;
import com.example.myapplication.R;
import com.lonelypluto.pdflibrary.utils.SharedPreferencesUtil;

import java.util.concurrent.Executor;

/**
 * @Description: 一些主要方法的设置,在已有功能的基础上增加了一些动态设置参数的方法
 * @author: ZhangYW
 * @time: 2019/3/11 15:56
 */
public class MoreSetActivity extends AppCompatActivity {
    private static final String TAG = MoreSetActivity.class.getSimpleName();
    private final int OUTLINE_REQUEST = 0;// 目录回调
    private String filePath = Environment.getExternalStorageDirectory() + "/Download/预通知.pdf"; // 文件路径



    private AlertDialog.Builder mAlertBuilder;// 弹出框

    private MuPDFCore muPDFCore;// 加载mupdf.so文件
    private MuPDFReaderView muPDFReaderView;// 显示pdf的view

    private boolean mAlertsActive = false;
    private AsyncTask mAlertTask;
    private AlertDialog mAlertDialog;// 初始加载pdf等待弹出框

    // tools
    private ViewAnimator mTopBarSwitcher;// 工具栏动画
    private ImageButton mLinkButton;// 超链接
    private ImageButton mOutlineButton;// 目录
    private ImageButton mSearchButton;// 搜索
    private ImageButton mAnnotButton;// 注释
    // tools 搜索框
    private EditText et_searchText;// 搜索内容输入框
    private ImageButton mSearchBack;// 搜索内容上一个
    private ImageButton mSearchFwd;// 搜索内容下一个
    // tools 注释类型
    private TextView mAnnotTypeText;// 注释类型
    // tools 底部布局
    private TextView mPageNumberView;// 页数
    private SeekBar mPageSlider;// 底部拖动条

    private int mPageSliderRes;// 拖动条的个数
    private boolean mButtonsVisible;// 是否显示工具栏
    private TopBarMode mTopBarMode = TopBarMode.Main;// 工具栏类型
    private AcceptMode mAcceptMode;// 工具栏注释类型

    private SearchTask mSearchTask;// 搜索线程
    private boolean mLinkHighlight = false;// 是否高亮显示

    private Button btn_change_hv;// 切换横竖显示
    private boolean ischangeHV = false;// 横竖切换
    private Button btn_linkhighlightcolor;// 设置超链接颜色
    private Button btn_searchtextcolor;// 设置搜索文字颜色
    private Button btn_paintcolor;// 设置画笔颜色
    private Button btn_paintstrokewidth;// 设置画笔粗细

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_more_set);
        initView();
    }

    /**
     * 初始化
     */
    private void initView() {
        SharedPreferencesUtil.init(getApplication());

        muPDFReaderView = (MuPDFReaderView)findViewById(R.id.mupdfreaderview);

        initToolsView();
        createPDF();
        setPDFVoid();
    }

    private void setPDFVoid(){
        //切换横竖显示
        btn_change_hv = (Button)findViewById(R.id.btn_change_hv);
        btn_change_hv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ischangeHV) {
                    muPDFReaderView.setHorizontalScrolling(ischangeHV);
                    btn_change_hv.setText("横");
                    ischangeHV = false;
                } else {
                    muPDFReaderView.setHorizontalScrolling(ischangeHV);
                    btn_change_hv.setText("竖");
                    ischangeHV = true;
                }
            }
        });

        // 改变超链接颜色
        btn_linkhighlightcolor = (Button)findViewById(R.id.btn_linkhighlightcolor);
        btn_linkhighlightcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setLinkHighlightColor(ContextCompat.getColor(MoreSetActivity.this, com.lonelypluto.pdflibrary.R.color.link_bg));
            }
        });

        // 改变搜索文字颜色
        btn_searchtextcolor = (Button)findViewById(R.id.btn_searchtextcolor);
        btn_searchtextcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setSearchTextColor(ContextCompat.getColor(MoreSetActivity.this, com.lonelypluto.pdflibrary.R.color.search_bg));
            }
        });

        // 设置画笔颜色
        btn_paintcolor = (Button)findViewById(R.id.btn_set_paint_color);
        btn_paintcolor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int c = ContextCompat.getColor(MoreSetActivity.this, com.lonelypluto.pdflibrary.R.color.rv_item_line_bg);
                setInkColor(0xFF0000FF);
            }
        });

        // 设置画笔粗细
        btn_paintstrokewidth = (Button)findViewById(R.id.btn_set_paint_strokewidth);
        btn_paintstrokewidth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setPaintStrockWidth(20.0f);
            }
        });
    }

    /**
     * 初始化工具栏
     */
    private void initToolsView() {

        mTopBarSwitcher = (ViewAnimator) findViewById(R.id.switcher);
        mLinkButton = (ImageButton) findViewById(R.id.linkButton);
        mAnnotButton = (ImageButton) findViewById(R.id.reflowButton);
        mOutlineButton = (ImageButton) findViewById(R.id.outlineButton);
        mSearchButton = (ImageButton) findViewById(R.id.searchButton);

        et_searchText = (EditText) findViewById(R.id.searchText);
        mSearchBack = (ImageButton) findViewById(R.id.searchBack);
        mSearchFwd = (ImageButton) findViewById(R.id.searchForward);

        mAnnotTypeText = (TextView) findViewById(R.id.annotType);

        mPageNumberView = (TextView) findViewById(R.id.pageNumber);
        mPageSlider = (SeekBar) findViewById(R.id.pageSlider);

        mTopBarSwitcher.setVisibility(View.INVISIBLE);
        mPageNumberView.setVisibility(View.INVISIBLE);
        mPageSlider.setVisibility(View.INVISIBLE);
    }

    private void createPDF() {
        mAlertBuilder  = new AlertDialog.Builder(this);

        // 通过MuPDFCore打开pdf文件
        muPDFCore = openFile(filePath);
        // 搜索设为空
        SearchTaskResult.set(null);
        // 判断如果core为空,提示不能打开文件
        if (muPDFCore == null) {
            AlertDialog alert = mAlertBuilder.create();
            alert.setTitle(com.lonelypluto.pdflibrary.R.string.cannot_open_document);
            alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(com.lonelypluto.pdflibrary.R.string.dismiss),
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    });
            alert.setOnCancelListener(new DialogInterface.OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog) {
                    finish();
                }
            });
            alert.show();
            return;
        }
        // 显示
        muPDFReaderView.setAdapter(new MuPDFPageAdapter(this, muPDFCore));
        // Set up the page slider
        int smax = Math.max(muPDFCore.countPages() - 1, 1);
        mPageSliderRes = ((10 + smax - 1) / smax) * 2;

        // 创建搜索任务
        mSearchTask = new SearchTask(this, muPDFCore) {
            @Override
            protected void onTextFound(SearchTaskResult result) {
                SearchTaskResult.set(result);
                // Ask the ReaderView to move to the resulting page
                muPDFReaderView.setDisplayedViewIndex(result.pageNumber);
                // Make the ReaderView act on the change to SearchTaskResult
                // via overridden onChildSetup method.
                muPDFReaderView.resetupChildren();
            }
        };

        // Search invoking buttons are disabled while there is no text specified
        mSearchBack.setEnabled(false);
        mSearchFwd.setEnabled(false);
        mSearchBack.setColorFilter(Color.argb(0xFF, 250, 250, 250));
        mSearchFwd.setColorFilter(Color.argb(0xFF, 250, 250, 250));

        // 判断如果pdf文件有目录
        if (muPDFCore.hasOutline()) {
            // 点击目录按钮跳转到目录页
            mOutlineButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    OutlineItem outline[] = muPDFCore.getOutline();
                    if (outline != null) {
                        OutlineActivityData.get().items = outline;
                        Intent intent = new Intent(MoreSetActivity.this, OutlineActivity.class);
                        startActivityForResult(intent, OUTLINE_REQUEST);
                    }
                }
            });
        } else {
            mOutlineButton.setVisibility(View.GONE);
        }

        // 设置监听事件
        setListener();
    }

    /**
     * 打开文件
     * @param path 文件路径
     * @return
     */
    private MuPDFCore openFile(String path) {

        Log.e(TAG, "Trying to open " + path);
        try {
            muPDFCore = new MuPDFCore(this, path);
            // 新建:删除旧的目录数据
            OutlineActivityData.set(null);
        } catch (Exception e) {
            Log.e(TAG, "openFile catch:" + e.toString());
            return null;
        } catch (OutOfMemoryError e) {
            //  out of memory is not an Exception, so we catch it separately.
            Log.e(TAG, "openFile catch: OutOfMemoryError " + e.toString());
            return null;
        }
        return muPDFCore;
    }

    /**
     * 设置监听事件
     */
    private void setListener(){
        // 设置MuPDFReaderView的监听事件
        setMuPDFReaderViewListener();
        // 设置页面拖动条监听事件
        mPageSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            public void onStopTrackingTouch(SeekBar seekBar) {
                muPDFReaderView.setDisplayedViewIndex((seekBar.getProgress() + mPageSliderRes / 2) / mPageSliderRes);
            }

            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                updatePageNumView((progress + mPageSliderRes / 2) / mPageSliderRes);
            }
        });
        // 搜索按钮
        mSearchButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                searchModeOn();
            }
        });
        // 注释按钮
        if (muPDFCore.fileFormat().startsWith("PDF") && muPDFCore.isUnencryptedPDF() && !muPDFCore.wasOpenedFromBuffer()) {
            mAnnotButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    mTopBarMode = TopBarMode.Annot;
                    mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                }
            });
        } else {
            mAnnotButton.setVisibility(View.GONE);
        }
        // 搜索的输入框监听事件
        et_searchText.addTextChangedListener(new TextWatcher() {

            public void afterTextChanged(Editable s) {
                boolean haveText = s.toString().length() > 0;
                setButtonEnabled(mSearchBack, haveText);
                setButtonEnabled(mSearchFwd, haveText);

                // Remove any previous search results
                if (SearchTaskResult.get() != null && !et_searchText.getText().toString().equals(SearchTaskResult.get().txt)) {
                    SearchTaskResult.set(null);
                    muPDFReaderView.resetupChildren();
                }
            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
            }

            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
            }
        });

        //React to Done button on keyboard
        et_searchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE)
                    search(1);
                return false;
            }
        });

        et_searchText.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER)
                    search(1);
                return false;
            }
        });

        // Activate search invoking buttons
        mSearchBack.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                search(-1);
            }
        });
        mSearchFwd.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                search(1);
            }
        });

        mLinkButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                setLinkHighlight(!mLinkHighlight);
            }
        });
    }

    /**
     * 设置MuPDFReaderView的监听事件
     */
    private void setMuPDFReaderViewListener(){
        muPDFReaderView.setListener(new MuPDFReaderViewListener() {
            @Override
            public void onMoveToChild(int i) {
                if (muPDFCore == null) {
                    return;
                }
                mPageNumberView.setText(String.format("%d / %d", i + 1,
                        muPDFCore.countPages()));
                mPageSlider.setMax((muPDFCore.countPages() - 1) * mPageSliderRes);
                mPageSlider.setProgress(i * mPageSliderRes);
            }

            @Override
            public void onTapMainDocArea() {
                if (!mButtonsVisible) {
                    showButtons();
                } else {
                    if (mTopBarMode == TopBarMode.Main)
                        hideButtons();
                }
            }

            @Override
            public void onDocMotion() {
                hideButtons();
            }

            @Override
            public void onHit(Hit item) {
                switch (mTopBarMode) {
                    case Annot:
                        if (item == Hit.Annotation) {
                            showButtons();
                            mTopBarMode = TopBarMode.Delete;
                            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                        }
                        break;
                    case Delete:
                        mTopBarMode = TopBarMode.Annot;
                        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
                        // fall through
                    default:
                        // Not in annotation editing mode, but the pageview will
                        // still select and highlight hit annotations, so
                        // deselect just in case.
                        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
                        if (pageView != null) {
                            pageView.deselectAnnotation();
                        }
                        break;
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            // 目录回调
            case OUTLINE_REQUEST:
                if (resultCode >= 0)
                    muPDFReaderView.setDisplayedViewIndex(resultCode);
                break;
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 设置超链接颜色
     * @param color 颜色值
     */
    private void setLinkHighlightColor(int color) {
        muPDFReaderView.setLinkHighlightColor(color);
    }

    /**
     * 设置搜索文字颜色
     * @param color 颜色值
     */
    private void setSearchTextColor(int color) {
        muPDFReaderView.setSearchTextColor(color);
    }

    /**
     * 设置画笔颜色
     * @param color 颜色值
     */
    private void setInkColor(int color) {
        muPDFReaderView.setInkColor(color);
    }

    /**
     * 设置画笔粗细
     * @param inkThickness 粗细值
     */
    private void setPaintStrockWidth(float inkThickness) {
        muPDFReaderView.setPaintStrockWidth(inkThickness);
    }

    /**
     * 显示工具栏
     */
    private void showButtons() {
        if (muPDFCore == null)
            return;
        if (!mButtonsVisible) {
            mButtonsVisible = true;
            // Update page number text and slider
            int index = muPDFReaderView.getDisplayedViewIndex();
            updatePageNumView(index);
            mPageSlider.setMax((muPDFCore.countPages() - 1) * mPageSliderRes);
            mPageSlider.setProgress(index * mPageSliderRes);
            if (mTopBarMode == TopBarMode.Search) {
                et_searchText.requestFocus();
                showKeyboard();
            }

            Animation anim = new TranslateAnimation(0, 0, -mTopBarSwitcher.getHeight(), 0);
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mTopBarSwitcher.setVisibility(View.VISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                }
            });
            mTopBarSwitcher.startAnimation(anim);

            anim = new TranslateAnimation(0, 0, mPageSlider.getHeight(), 0);
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mPageSlider.setVisibility(View.VISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mPageNumberView.setVisibility(View.VISIBLE);
                }
            });
            mPageSlider.startAnimation(anim);
        }
    }

    /**
     * 隐藏工具栏
     */
    private void hideButtons() {
        if (mButtonsVisible) {
            mButtonsVisible = false;
            hideKeyboard();

            Animation anim = new TranslateAnimation(0, 0, 0, -mTopBarSwitcher.getHeight());
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mTopBarSwitcher.setVisibility(View.INVISIBLE);
                }
            });
            mTopBarSwitcher.startAnimation(anim);

            anim = new TranslateAnimation(0, 0, 0, mPageSlider.getHeight());
            anim.setDuration(200);
            anim.setAnimationListener(new Animation.AnimationListener() {
                public void onAnimationStart(Animation animation) {
                    mPageNumberView.setVisibility(View.INVISIBLE);
                }

                public void onAnimationRepeat(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    mPageSlider.setVisibility(View.INVISIBLE);
                }
            });
            mPageSlider.startAnimation(anim);
        }
    }

    /**
     * 更新当前是第多少页
     * @param index
     */
    private void updatePageNumView(int index) {
        if (muPDFCore == null)
            return;
        mPageNumberView.setText(String.format("%d / %d", index + 1, muPDFCore.countPages()));
    }

    /**
     * 显示键盘
     */
    private void showKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null)
            imm.showSoftInput(et_searchText, 0);
    }

    /**
     * 隐藏键盘
     */
    private void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null)
            imm.hideSoftInputFromWindow(et_searchText.getWindowToken(), 0);
    }

    /**
     * 工具栏 - 注释点击事件
     * @param v
     */
    public void OnEditAnnotButtonClick(View v) {
        mTopBarMode = TopBarMode.Main;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 复制点击事件
     * @param v
     */
    public void OnCopyTextButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.CopyText;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(getString(com.lonelypluto.pdflibrary.R.string.copy_text));
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 搜索框取消点击事件
     * @param v
     */
    public void OnCancelSearchButtonClick(View v) {
        searchModeOff();
    }

    /**
     * 工具栏 - 注释取消点击事件
     * @param v
     */
    public void OnCancelMoreButtonClick(View v) {
        mTopBarMode = TopBarMode.Main;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 开始搜索
     */
    private void searchModeOn() {
        if (mTopBarMode != TopBarMode.Search) {
            mTopBarMode = TopBarMode.Search;
            //Focus on EditTextWidget
            et_searchText.requestFocus();
            showKeyboard();
            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        }
    }

    /**
     * 取消搜索
     */
    private void searchModeOff() {
        if (mTopBarMode == TopBarMode.Search) {
            mTopBarMode = TopBarMode.Main;
            hideKeyboard();
            mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
            SearchTaskResult.set(null);
            // Make the ReaderView act on the change to mSearchTaskResult
            // via overridden onChildSetup method.
            muPDFReaderView.resetupChildren();
        }
    }

    /**
     * 工具栏 - 注释 - 高亮点击事件
     * @param v
     */
    public void OnHighlightButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Highlight;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_highlight);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 底部画线点击事件
     * @param v
     */
    public void OnUnderlineButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Underline;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_underline);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 废弃线点击事件
     * @param v
     */
    public void OnStrikeOutButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.StrikeOut;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Selecting);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_strike_out);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.select_text));
    }

    /**
     * 工具栏 - 注释 - 签字点击事件
     * @param v
     */
    public void OnInkButtonClick(View v) {
        mTopBarMode = TopBarMode.Accept;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        mAcceptMode = AcceptMode.Ink;
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Drawing);
        mAnnotTypeText.setText(com.lonelypluto.pdflibrary.R.string.pdf_tools_ink);
        showInfo(getString(com.lonelypluto.pdflibrary.R.string.pdf_tools_draw_annotation));
    }

    /**
     * 工具栏 - 注释 - 删除注释点击事件
     * @param v
     */
    public void OnDeleteButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null)
            pageView.deleteSelectedAnnotation();
        mTopBarMode = TopBarMode.Annot;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 取消删除注释点击事件
     * @param v
     */
    public void OnCancelDeleteButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null)
            pageView.deselectAnnotation();
        mTopBarMode = TopBarMode.Annot;
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 取消点击事件
     * @param v
     */
    public void OnCancelAcceptButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        if (pageView != null) {
            pageView.deselectText();
            pageView.cancelDraw();
        }
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Viewing);
        switch (mAcceptMode) {
            case CopyText:
                mTopBarMode = TopBarMode.Main;
                break;
            default:
                mTopBarMode = TopBarMode.Annot;
                break;
        }
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
    }

    /**
     * 工具栏 - 注释 - 确定点击事件
     * @param v
     */
    public void OnAcceptButtonClick(View v) {
        MuPDFView pageView = (MuPDFView) muPDFReaderView.getDisplayedView();
        boolean success = false;
        switch (mAcceptMode) {
            case CopyText:
                if (pageView != null)
                    success = pageView.copySelection();
                mTopBarMode = TopBarMode.Main;
                showInfo(success ? getString(com.lonelypluto.pdflibrary.R.string.copied_to_clipboard) : getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;
            case Highlight:
                // 高亮
                if (pageView != null) {
                    success = pageView.markupSelection(Annotation.Type.HIGHLIGHT);
                }
                mTopBarMode = TopBarMode.Annot;
                if (!success) {
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                }
                break;
            case Underline:
                if (pageView != null)
                    success = pageView.markupSelection(Annotation.Type.UNDERLINE);
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;

            case StrikeOut:
                if (pageView != null)
                    success = pageView.markupSelection(Annotation.Type.STRIKEOUT);
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.no_text_selected));
                break;

            case Ink:
                if (pageView != null)
                    success = pageView.saveDraw();
                mTopBarMode = TopBarMode.Annot;
                if (!success)
                    showInfo(getString(com.lonelypluto.pdflibrary.R.string.nothing_to_save));
                break;
        }
        mTopBarSwitcher.setDisplayedChild(mTopBarMode.ordinal());
        muPDFReaderView.setMode(MuPDFReaderView.Mode.Viewing);
    }

    /**
     * 设置按钮是否可点击
     * @param button
     * @param enabled
     */
    private void setButtonEnabled(ImageButton button, boolean enabled) {
        button.setEnabled(enabled);
        button.setColorFilter(enabled ? Color.argb(0xFF, 250, 250, 250) : Color.argb(0xFF, 250, 250, 250));
    }

    /**
     * 开始搜索
     * @param direction 搜索内容
     */
    private void search(int direction) {
        hideKeyboard();
        int displayPage = muPDFReaderView.getDisplayedViewIndex();
        SearchTaskResult r = SearchTaskResult.get();
        int searchPage = r != null ? r.pageNumber : -1;
        mSearchTask.go(et_searchText.getText().toString(), direction, displayPage, searchPage);
    }

    /**
     * 设置超链接高亮显示
     * @param highlight
     */
    private void setLinkHighlight(boolean highlight) {
        mLinkHighlight = highlight;
        // LINK_COLOR tint
        mLinkButton.setColorFilter(highlight ? Color.argb(0xFF, 255, 160, 0) : Color.argb(0xFF, 255, 255, 255));
        // Inform pages of the change.
        muPDFReaderView.setLinksEnabled(highlight);
    }

    /**
     * 工具栏弹出提示信息
     * @param message 提示内容
     */
    private void showInfo(String message) {

        LayoutInflater inflater = getLayoutInflater();
        View toastLayout = inflater.inflate(com.lonelypluto.pdflibrary.R.layout.toast,
                (ViewGroup) findViewById(com.lonelypluto.pdflibrary.R.id.toast_root_view));

        TextView header = (TextView) toastLayout.findViewById(com.lonelypluto.pdflibrary.R.id.toast_message);
        header.setText(message);

        Toast toast = new Toast(getApplicationContext());
        toast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.BOTTOM, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(toastLayout);
        toast.show();
    }

    /**
     * 创建提示等待
     */
    public void createAlertWaiter() {
        mAlertsActive = true;
        // All mupdf library calls are performed on asynchronous tasks to avoid stalling
        // the UI. Some calls can lead to javascript-invoked requests to display an
        // alert dialog and collect a reply from the user. The task has to be blocked
        // until the user's reply is received. This method creates an asynchronous task,
        // the purpose of which is to wait of these requests and produce the dialog
        // in response, while leaving the core blocked. When the dialog receives the
        // user's response, it is sent to the core via replyToAlert, unblocking it.
        // Another alert-waiting task is then created to pick up the next alert.
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
        if (mAlertDialog != null) {
            mAlertDialog.cancel();
            mAlertDialog = null;
        }
        mAlertTask = new AsyncTask() {

            @Override
            protected MuPDFAlert doInBackground(Void... arg0) {
                if (!mAlertsActive)
                    return null;

                return muPDFCore.waitForAlert();
            }

            @Override
            protected void onPostExecute(final MuPDFAlert result) {
                // core.waitForAlert may return null when shutting down
                if (result == null)
                    return;
                final MuPDFAlert.ButtonPressed pressed[] = new MuPDFAlert.ButtonPressed[3];
                for (int i = 0; i < 3; i++)
                    pressed[i] = MuPDFAlert.ButtonPressed.None;
                DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        mAlertDialog = null;
                        if (mAlertsActive) {
                            int index = 0;
                            switch (which) {
                                case AlertDialog.BUTTON1:
                                    index = 0;
                                    break;
                                case AlertDialog.BUTTON2:
                                    index = 1;
                                    break;
                                case AlertDialog.BUTTON3:
                                    index = 2;
                                    break;
                            }
                            result.buttonPressed = pressed[index];
                            // Send the user's response to the core, so that it can
                            // continue processing.
                            muPDFCore.replyToAlert(result);
                            // Create another alert-waiter to pick up the next alert.
                            createAlertWaiter();
                        }
                    }
                };
                mAlertDialog = mAlertBuilder.create();
                mAlertDialog.setTitle(result.title);
                mAlertDialog.setMessage(result.message);
                switch (result.iconType) {
                    case Error:
                        break;
                    case Warning:
                        break;
                    case Question:
                        break;
                    case Status:
                        break;
                }
                switch (result.buttonGroupType) {
                    case OkCancel:
                        mAlertDialog.setButton(AlertDialog.BUTTON2, getString(com.lonelypluto.pdflibrary.R.string.cancel), listener);
                        pressed[1] = MuPDFAlert.ButtonPressed.Cancel;
                    case Ok:
                        mAlertDialog.setButton(AlertDialog.BUTTON1, getString(com.lonelypluto.pdflibrary.R.string.okay), listener);
                        pressed[0] = MuPDFAlert.ButtonPressed.Ok;
                        break;
                    case YesNoCancel:
                        mAlertDialog.setButton(AlertDialog.BUTTON3, getString(com.lonelypluto.pdflibrary.R.string.cancel), listener);
                        pressed[2] = MuPDFAlert.ButtonPressed.Cancel;
                    case YesNo:
                        mAlertDialog.setButton(AlertDialog.BUTTON1, getString(com.lonelypluto.pdflibrary.R.string.yes), listener);
                        pressed[0] = MuPDFAlert.ButtonPressed.Yes;
                        mAlertDialog.setButton(AlertDialog.BUTTON2, getString(com.lonelypluto.pdflibrary.R.string.no), listener);
                        pressed[1] = MuPDFAlert.ButtonPressed.No;
                        break;
                }
                mAlertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    public void onCancel(DialogInterface dialog) {
                        mAlertDialog = null;
                        if (mAlertsActive) {
                            result.buttonPressed = MuPDFAlert.ButtonPressed.None;
                            muPDFCore.replyToAlert(result);
                            createAlertWaiter();
                        }
                    }
                });

                mAlertDialog.show();
            }
        };

        mAlertTask.executeOnExecutor(new ThreadPerTaskExecutor());
    }

    /**
     * 销毁提示等待
     */
    public void destroyAlertWaiter() {
        mAlertsActive = false;
        if (mAlertDialog != null) {
            mAlertDialog.cancel();
            mAlertDialog = null;
        }
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
    }

    @Override
    protected void onStart() {
        if (muPDFCore != null) {
            muPDFCore.startAlerts();
            createAlertWaiter();
        }
        super.onStart();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mSearchTask != null) {
            mSearchTask.stop();
        }
    }

    @Override
    protected void onStop() {
        if (muPDFCore != null) {
            destroyAlertWaiter();
            muPDFCore.stopAlerts();
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        if (muPDFReaderView != null) {
            muPDFReaderView.applyToChildren(new ReaderView.ViewMapper() {
                public void applyToView(View view) {
                    ((MuPDFView) view).releaseBitmaps();
                }
            });
        }
        if (muPDFCore != null)
            muPDFCore.onDestroy();
        if (mAlertTask != null) {
            mAlertTask.cancel(true);
            mAlertTask = null;
        }
        muPDFCore = null;
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (muPDFCore != null && muPDFCore.hasChanges()) {
            DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    if (which == AlertDialog.BUTTON_POSITIVE) {
                        muPDFCore.save();
                    }
                    finish();
                }
            };
            AlertDialog alert = mAlertBuilder.create();
            alert.setTitle(com.lonelypluto.pdflibrary.R.string.dialog_title);
            alert.setMessage(getString(com.lonelypluto.pdflibrary.R.string.document_has_changes_save_them));
            alert.setButton(AlertDialog.BUTTON_POSITIVE, getString(com.lonelypluto.pdflibrary.R.string.yes), listener);
            alert.setButton(AlertDialog.BUTTON_NEGATIVE, getString(com.lonelypluto.pdflibrary.R.string.no), listener);
            alert.show();
        } else {
            finish();
        }
    }

    /**
     * 多线程类
     */
    class ThreadPerTaskExecutor implements Executor {
        public void execute(Runnable r) {
            new Thread(r).start();
        }
    }

    /**
     * 工具栏类型 Search:搜索 Annot:注释
     */
    enum TopBarMode {
        Main, Search, Annot, Delete, Accept
    }

    /**
     * 工具栏注释类型 Highlight:高亮显示 ,Underline:底部画线 ,StrikeOut:废弃线 ,Ink:签字 ,CopyText:复制文字
     */
    enum AcceptMode {
        Highlight, Underline, StrikeOut, Ink, CopyText
    }
}

1.14创建MoreSetActivity的activity_more_set.xml页面




    

    

    
        

1.15 activity配置



        
            
            

        
            
            

        

andorid实现pdf批注、笔记demo_第3张图片

1.16 设置文件权限

 
 

andorid实现pdf批注、笔记demo_第4张图片

1.17 java文件展示

andorid实现pdf批注、笔记demo_第5张图片

1.18 xml文件展示

andorid实现pdf批注、笔记demo_第6张图片

1.19运行项目报错

Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 17 declared in library [com.lonelypluto:pdf-viewer:1.0.5] C:\Users\yangkai.gradle\caches\transforms-1\files-1.1\pdf-viewer-1.0.5.aar\26470ca641a88cc4ca3b1dd0fff680b9\AndroidManifest.xml as the library might be using APIs not available in 16
Suggestion: use a compatible library with a minSdk of at most 16,
or increase this project’s minSdk version to at least 17,
or use tools:overrideLibrary=“com.lonelypluto.pdflibrary” to force usage (may lead to runtime failures)

需要修改sdk:minSdkVersion 版本:
andorid实现pdf批注、笔记demo_第7张图片
这里我修改为19,运行正常
打包运行正常
提示访问文件

1.19 如果文件不能打开

提示:Permission denied,需要设置手机或平板的存储储存权限
首先提示访问文件权限已经设置



平板为例设置权限:设置=>应用管理=>高级=>应用权限=>存储=>找到对应的app打开权限

3 成功效果

andorid实现pdf批注、笔记demo_第8张图片
andorid实现pdf批注、笔记demo_第9张图片
注意:权限是手机和代码都需要设置权限,才能完成pdf的读取
会存在的问题:ObjectBox的包和pdf的包存在不兼容性,会导致pdf运行失败!

如有帮助,打赏不限

你可能感兴趣的:(Android)