【问题标题】:Android: Display pdf in fragments using MuPDF [closed]Android:使用 MuPDF 在片段中显示 pdf [关闭]
【发布时间】:2015-01-08 11:03:38
【问题描述】:

我可以在片段中使用 MuPDF 显示 PDF,而不是在活动中显示。

解决了这个问题MuPDF for Android: Option for fragment instead Activity

但我无法解决我的问题,请任何人帮我解决。

【问题讨论】:

    标签: android


    【解决方案1】:

    我知道这不是最好的做法,但几天前我遇到了类似的问题,所以这就是我所做的

    编辑代码

    import android.app.AlertDialog;
    import android.app.Fragment;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.database.Cursor;
    import android.graphics.RectF;
    import android.net.Uri;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.view.*;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.view.inputmethod.EditorInfo;
    import android.view.inputmethod.InputMethodManager;
    import android.widget.*;
    import com.docutools.android.R;
    
    public class PdfViewer extends Fragment {
    
        /* The core rendering instance */
        private enum LinkState {
            DEFAULT, HIGHLIGHT, INHIBIT
        }
    
        ;
    
        public static final String KEY_INTENT_ACTION = "key.intent.action";
        private final int TAP_PAGE_MARGIN = 5;
        private static final int SEARCH_PROGRESS_DELAY = 200;
        private MuPDFCore core;
        private String mFileName;
        private ReaderView mDocView;
        private View mButtonsView;
        private boolean mButtonsVisible;
        private EditText mPasswordView;
        private TextView mFilenameView;
        private SeekBar mPageSlider;
        private int mPageSliderRes;
        private TextView mPageNumberView;
        private ImageButton mSearchButton;
        private ImageButton mCancelButton;
        private ImageButton mOutlineButton;
        private ViewSwitcher mTopBarSwitcher;
        // XXX  private ImageButton  mLinkButton;
        private boolean mTopBarIsSearch;
        private ImageButton mSearchBack;
        private ImageButton mSearchFwd;
        private EditText mSearchText;
        private SafeAsyncTask<Void, Integer, SearchTaskResult> mSearchTask;
        //private SearchTaskResult mSearchTaskResult;
        private AlertDialog.Builder mAlertBuilder;
        private LinkState mLinkState = LinkState.DEFAULT;
        private final Handler mHandler = new Handler();
    
        // send this as Fragment Argument
        protected Intent intent;
    
        public static PdfViewer getInstance(Intent intent) {
            PdfViewer pdfViewer = new PdfViewer();
    
            Bundle args = new Bundle();
            args.putParcelable(KEY_INTENT_ACTION, intent);
    
            pdfViewer.setArguments(args);
    
            return pdfViewer;
        }
    
        private MuPDFCore openFile(String path) {
            int lastSlashPos = path.lastIndexOf('/');
            mFileName = new String(lastSlashPos == -1
                    ? path
                    : path.substring(lastSlashPos + 1));
            System.out.println("Trying to open " + path);
            try {
                core = new MuPDFCore(path);
                // New file: drop the old outline data
                OutlineActivityData.set(null);
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
            return core;
        }
    
        /**
         * Called when the activity is first created.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            intent = getArguments().getParcelable(KEY_INTENT_ACTION);
    
            mAlertBuilder = new AlertDialog.Builder(getActivity());
    
            if (core == null) {
                if (Intent.ACTION_VIEW.equals(intent.getAction())) {
                    Uri uri = intent.getData();
                    if (uri.toString().startsWith("content://media/external/file")) {
                        // Handle view requests from the Transformer Prime's file manager
                        // Hopefully other file managers will use this same scheme, if not
                        // using explicit paths.
                        Cursor cursor = getActivity().getContentResolver().query(uri, new String[]{"_data"}, null, null, null);
                        if (cursor.moveToFirst()) {
                            uri = Uri.parse(cursor.getString(0));
                        }
                    }
                    core = openFile(Uri.decode(uri.getEncodedPath()));
                    SearchTaskResult.set(null);
                }
                if (core != null && core.needsPassword()) {
                    // requestPassword(savedInstanceState);
                    return;
                }
            }
            if (core == null) {
                AlertDialog alert = mAlertBuilder.create();
                alert.setTitle(com.artifex.mupdf.R.string.open_failed);
                alert.setButton(AlertDialog.BUTTON_POSITIVE, "Dismiss",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                getFragmentHolder().popFragment();
                            }
                        }
                );
                alert.show();
                return;
            }
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return createUI();
        }
    
        public RelativeLayout createUI() {
            if (core == null)
                return null;
            // Now create the UI.
            // First create the document view making use of the ReaderView's internal
            // gesture recognition
            mDocView = new ReaderView(getActivity()) {
                private boolean showButtonsDisabled;
    
                public boolean onSingleTapUp(MotionEvent e) {
                    if (e.getX() < super.getWidth() / TAP_PAGE_MARGIN) {
                        super.moveToPrevious();
                    } else if (e.getX() > super.getWidth() * (TAP_PAGE_MARGIN - 1) / TAP_PAGE_MARGIN) {
                        super.moveToNext();
                    } else if (!showButtonsDisabled) {
                        int linkPage = -1;
                        if (mLinkState != LinkState.INHIBIT) {
                            MuPDFPageView pageView = (MuPDFPageView) mDocView.getDisplayedView();
                            if (pageView != null) {
    // XXX                          linkPage = pageView.hitLinkPage(e.getX(), e.getY());
                            }
                        }
    
                        if (linkPage != -1) {
                            mDocView.setDisplayedViewIndex(linkPage);
                        } else {
                            if (!mButtonsVisible) {
                                showButtons();
                            } else {
                                hideButtons();
                            }
                        }
                    }
                    return super.onSingleTapUp(e);
                }
    
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                    if (!showButtonsDisabled)
                        hideButtons();
    
                    return super.onScroll(e1, e2, distanceX, distanceY);
                }
    
                public boolean onScaleBegin(ScaleGestureDetector d) {
                    // Disabled showing the buttons until next touch.
                    // Not sure why this is needed, but without it
                    // pinch zoom can make the buttons appear
                    showButtonsDisabled = true;
                    return super.onScaleBegin(d);
                }
    
                public boolean onTouchEvent(MotionEvent event) {
                    if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
                        showButtonsDisabled = false;
    
                    return super.onTouchEvent(event);
                }
    
                protected void onChildSetup(int i, View v) {
                    if (SearchTaskResult.get() != null && SearchTaskResult.get().pageNumber == i)
                        ((PageView) v).setSearchBoxes(SearchTaskResult.get().searchBoxes);
                    else
                        ((PageView) v).setSearchBoxes(null);
    
                    ((PageView) v).setLinkHighlighting(mLinkState == LinkState.HIGHLIGHT);
                }
    
                protected void onMoveToChild(int i) {
                    if (core == null)
                        return;
                    mPageNumberView.setText(String.format("%d/%d", i + 1, core.countPages()));
                    mPageSlider.setMax((core.countPages() - 1) * mPageSliderRes);
                    mPageSlider.setProgress(i * mPageSliderRes);
                    if (SearchTaskResult.get() != null && SearchTaskResult.get().pageNumber != i) {
                        SearchTaskResult.set(null);
                        mDocView.resetupChildren();
                    }
                }
    
                protected void onSettle(View v) {
                    // When the layout has settled ask the page to render
                    // in HQ
                    ((PageView) v).addHq();
                }
    
                protected void onUnsettle(View v) {
                    // When something changes making the previous settled view
                    // no longer appropriate, tell the page to remove HQ
                    ((PageView) v).removeHq();
                }
    
                @Override
                protected void onNotInUse(View v) {
                    ((PageView) v).releaseResources();
                }
            };
            mDocView.setAdapter(new MuPDFPageAdapter(getActivity(), core));
    
            // Make the buttons overlay, and store all its
            // controls in variables
            makeButtonsView();
    
            // Set up the page slider
            int smax = Math.max(core.countPages() - 1, 1);
            mPageSliderRes = ((10 + smax - 1) / smax) * 2;
    
            // Set the file-name text
            mFilenameView.setText(mFileName);
    
            // Activate the seekbar
            mPageSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                public void onStopTrackingTouch(SeekBar seekBar) {
                    mDocView.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.setVisibility(View.INVISIBLE);
            // Activate the search-preparing button
            mSearchButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    searchModeOn();
                }
            });
    
            mCancelButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    searchModeOff();
                }
            });
    
            // Search invoking buttons are disabled while there is no text specified
            mSearchBack.setEnabled(false);
            mSearchFwd.setEnabled(false);
    
            // React to interaction with the text widget
            mSearchText.addTextChangedListener(new TextWatcher() {
    
                public void afterTextChanged(Editable s) {
                    boolean haveText = s.toString().length() > 0;
                    mSearchBack.setEnabled(haveText);
                    mSearchFwd.setEnabled(haveText);
    
                    // Remove any previous search results
                    if (SearchTaskResult.get() != null && !mSearchText.getText().toString().equals(SearchTaskResult.get().txt)) {
                        SearchTaskResult.set(null);
                        mDocView.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);
                }
            });
    
    /* XXX
            mLinkButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    switch(mLinkState) {
                    case DEFAULT:
                        mLinkState = LinkState.HIGHLIGHT;
                        mLinkButton.setImageResource(R.drawable.ic_hl_link);
                        //Inform pages of the change.
                        mDocView.resetupChildren();
                        break;
                    case HIGHLIGHT:
                        mLinkState = LinkState.INHIBIT;
                        mLinkButton.setImageResource(R.drawable.ic_nolink);
                        //Inform pages of the change.
                        mDocView.resetupChildren();
                        break;
                    case INHIBIT:
                        mLinkState = LinkState.DEFAULT;
                        mLinkButton.setImageResource(R.drawable.ic_link);
                        break;
                    }
                }
            });
    */
    
            if (core.hasOutline()) {
                mOutlineButton.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        OutlineItem outline[] = core.getOutline();
                        if (outline != null) {
                            OutlineActivityData.get().items = outline;
                            Intent intent = new Intent(getActivity(), OutlineActivity.class);
                            startActivityForResult(intent, 0);
                        }
                    }
                });
            } else {
                mOutlineButton.setVisibility(View.GONE);
            }
    
            // Reenstate last state if it was recorded
            SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
            mDocView.setDisplayedViewIndex(prefs.getInt("page" + mFileName, 0));
    
           /* if (savedInstanceState == null || !savedInstanceState.getBoolean("ButtonsHidden", false))
                showButtons();
    
            if(savedInstanceState != null && savedInstanceState.getBoolean("SearchMode", false))
                searchModeOn();*/
    
            // Stick the document view and the buttons overlay into a parent view
            RelativeLayout layout = new RelativeLayout(getActivity());
            layout.addView(mDocView);
            layout.addView(mButtonsView);
            layout.setBackgroundResource(R.drawable.tiled_background);
            //layout.setBackgroundResource(R.color.canvas);
            return layout;
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode >= 0)
                mDocView.setDisplayedViewIndex(resultCode);
            super.onActivityResult(requestCode, resultCode, data);
        }
    
        @Override
        public void onPause() {
            super.onPause();
    
            killSearch();
    
            if (mFileName != null && mDocView != null) {
                SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
                SharedPreferences.Editor edit = prefs.edit();
                edit.putInt("page" + mFileName, mDocView.getDisplayedViewIndex());
                edit.commit();
            }
        }
    
        public void onDestroy() {
            if (core != null)
                core.onDestroy();
            core = null;
            super.onDestroy();
        }
    
        void showButtons() {
            if (core == null)
                return;
            if (!mButtonsVisible) {
                mButtonsVisible = true;
                // Update page number text and slider
                int index = mDocView.getDisplayedViewIndex();
                updatePageNumView(index);
                mPageSlider.setMax((core.countPages() - 1) * mPageSliderRes);
                mPageSlider.setProgress(index * mPageSliderRes);
                if (mTopBarIsSearch) {
                    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);
            }
        }
    
        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);
            }
        }
    
        void searchModeOn() {
            if (!mTopBarIsSearch) {
                mTopBarIsSearch = true;
                //Focus on EditTextWidget
                mSearchText.requestFocus();
                showKeyboard();
                mTopBarSwitcher.showNext();
            }
        }
    
        void searchModeOff() {
            if (mTopBarIsSearch) {
                mTopBarIsSearch = false;
                hideKeyboard();
                mTopBarSwitcher.showPrevious();
                SearchTaskResult.set(null);
                // Make the ReaderView act on the change to mSearchTaskResult
                // via overridden onChildSetup method.
                mDocView.resetupChildren();
            }
        }
    
        void updatePageNumView(int index) {
            if (core == null)
                return;
            mPageNumberView.setText(String.format("%d/%d", index + 1, core.countPages()));
        }
    
        void makeButtonsView() {
            mButtonsView = getActivity().getLayoutInflater().inflate(R.layout.buttons, null);
            mFilenameView = (TextView) mButtonsView.findViewById(R.id.docNameText);
            mPageSlider = (SeekBar) mButtonsView.findViewById(R.id.pageSlider);
            mPageNumberView = (TextView) mButtonsView.findViewById(R.id.pageNumber);
            mSearchButton = (ImageButton) mButtonsView.findViewById(R.id.searchButton);
            mCancelButton = (ImageButton) mButtonsView.findViewById(R.id.cancel);
            mOutlineButton = (ImageButton) mButtonsView.findViewById(R.id.outlineButton);
            mTopBarSwitcher = (ViewSwitcher) mButtonsView.findViewById(R.id.switcher);
            mSearchBack = (ImageButton) mButtonsView.findViewById(R.id.searchBack);
            mSearchFwd = (ImageButton) mButtonsView.findViewById(R.id.searchForward);
            mSearchText = (EditText) mButtonsView.findViewById(R.id.searchText);
    // XXX      mLinkButton = (ImageButton)mButtonsView.findViewById(R.id.linkButton);
            mTopBarSwitcher.setVisibility(View.INVISIBLE);
            mPageNumberView.setVisibility(View.INVISIBLE);
            mPageSlider.setVisibility(View.INVISIBLE);
        }
    
        void showKeyboard() {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null)
                imm.showSoftInput(mSearchText, 0);
        }
    
        void hideKeyboard() {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null)
                imm.hideSoftInputFromWindow(mSearchText.getWindowToken(), 0);
        }
    
        void killSearch() {
            if (mSearchTask != null) {
                mSearchTask.cancel(true);
                mSearchTask = null;
            }
        }
    
        void search(int direction) {
            hideKeyboard();
            if (core == null)
                return;
            killSearch();
    
            final int increment = direction;
            final int startIndex = SearchTaskResult.get() == null ? mDocView.getDisplayedViewIndex() : SearchTaskResult.get().pageNumber + increment;
    
            final ProgressDialogX progressDialog = new ProgressDialogX(getActivity());
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setTitle(getString(R.string.searching_));
            progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                public void onCancel(DialogInterface dialog) {
                    killSearch();
                }
            });
            progressDialog.setMax(core.countPages());
    
            mSearchTask = new SafeAsyncTask<Void, Integer, SearchTaskResult>() {
                @Override
                protected SearchTaskResult doInBackground(Void... params) {
                    int index = startIndex;
    
                    while (0 <= index && index < core.countPages() && !isCancelled()) {
                        publishProgress(index);
                        RectF searchHits[] = core.searchPage(index, mSearchText.getText().toString());
    
                        if (searchHits != null && searchHits.length > 0)
                            return new SearchTaskResult(mSearchText.getText().toString(), index, searchHits);
    
                        index += increment;
                    }
                    return null;
                }
    
                @Override
                protected void onPostExecute(SearchTaskResult result) {
                    progressDialog.cancel();
                    if (result != null) {
                        // Ask the ReaderView to move to the resulting page
                        mDocView.setDisplayedViewIndex(result.pageNumber);
                        SearchTaskResult.set(result);
                        // Make the ReaderView act on the change to mSearchTaskResult
                        // via overridden onChildSetup method.
                        mDocView.resetupChildren();
                    } else {
                        mAlertBuilder.setTitle(SearchTaskResult.get() == null ? R.string.text_not_found : R.string.no_further_occurences_found);
                        AlertDialog alert = mAlertBuilder.create();
                        alert.setButton(AlertDialog.BUTTON_POSITIVE, "Dismiss",
                                (DialogInterface.OnClickListener) null);
                        alert.show();
                    }
                }
    
                @Override
                protected void onCancelled() {
                    super.onCancelled();
                    progressDialog.cancel();
                }
    
                @Override
                protected void onProgressUpdate(Integer... values) {
                    super.onProgressUpdate(values);
                    progressDialog.setProgress(values[0].intValue());
                }
    
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    mHandler.postDelayed(new Runnable() {
                        public void run() {
                            if (!progressDialog.isCancelled()) {
                                progressDialog.show();
                                progressDialog.setProgress(startIndex);
                            }
                        }
                    }, SEARCH_PROGRESS_DELAY);
                }
            };
    
            mSearchTask.safeExecute();
        }
    }
    
    class ProgressDialogX extends ProgressDialog {
        public ProgressDialogX(Context context) {
            super(context);
        }
    
        private boolean mCancelled = false;
    
        public boolean isCancelled() {
            return mCancelled;
        }
    
        @Override
        public void cancel() {
            mCancelled = true;
            super.cancel();
        }
    }
    
    class SearchTaskResult {
        public final String txt;
        public final int   pageNumber;
        public final RectF searchBoxes[];
        static private SearchTaskResult singleton;
    
        SearchTaskResult(String _txt, int _pageNumber, RectF _searchBoxes[]) {
            txt = _txt;
            pageNumber = _pageNumber;
            searchBoxes = _searchBoxes;
        }
    
        static public SearchTaskResult get() {
            return singleton;
        }
    
        static public void set(SearchTaskResult r) {
            singleton = r;
        }
    }
    

    用法

    使用PdfViewer.getInstance(intent);获取PdfViewer的实例

    【讨论】:

    • 你能告诉我如何为相应的列表项点击放置文件吗..在我的应用程序中它只显示第一项..
    • shubhang.. 请告诉我如何将意图作为片段参数传递,如果你这样做了,请分享代码。谢谢..
    • @namitha 我的代码更新了,请看一下
    • SafeAsyncTask 类型的参数数量不正确;它不能用参数 参数化我收到此错误。 .addHq 也会出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2015-04-17
    • 2017-04-10
    • 2011-03-03
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多