DImuthuUpe / AndroidPdfViewer

Android view for displaying PDFs rendered with PdfiumAndroid
Apache License 2.0
8.17k stars 1.91k forks source link

Using RecyclerView gives blank page #200

Open abhijeethallur opened 7 years ago

abhijeethallur commented 7 years ago

Hi, I am trying to use PDFViewer inside a RecyclerView as my requirement is to render multiple PDF files consisting single page each. The pages are rendered perfectly for the first time, but when I scroll to bottom of RecyclerView and again scroll back to previous pages then I am getting blank views. Can anyone suggest me a way to overcome this and let me know if I am trying to do it in an wrong way. Any help is appreciated, thanks.

doubledeath commented 7 years ago

a little difficult to tell without at least code or logs, but check this issue #195 and try fork #196 , your situation is similar like mine, maybe it gonna help you

abhijeethallur commented 7 years ago

@doubledeath Thanks for the reply. My apologies for not posting the code. I have found the solution for my problem and it is very simple. I just had to load the pdf in the onViewAttachedToWindow() method inside the RecyclerView's Adapter. Now the pages are not blank.

But I am facing a new problem that is the recyclerview scroll is getting sticky. This is probably because of pdfView.load() method. Any idea on how can I achieve smooth scroll for recyclerview?

@Override
public void onViewAttachedToWindow(DataObjectHolder holder) {
    super.onViewAttachedToWindow(holder);
    final DataObjectHolder dh = holder;
    final int pos = holder.getAdapterPosition();
    dh.pdfView.fromAsset(mPdfPathsList.get(pos))
            .enableDoubletap(true)
            .enableAnnotationRendering(true)
            .onPageScroll(new OnPageScrollListener() {
                @Override
                public void onPageScrolled(int page, float positionOffset) {
                    if (positionOffset == 0 || positionOffset == 1) {
                        dh.pdfView.resetZoom();
                        dh.pdfView.scrollTo(0, 0);
                    }
                }
            })
            .load();
}

Below is my Log

02-20 13:20:32.569 27742-27742/com1.example.abhijeethallur.pdfexample I/Choreographer: Skipped 94 frames! The application may be doing too much work on its main thread. 02-20 13:20:44.293 27742-28133/com1.example.abhijeethallur.pdfexample E/com.shockwave.pdfium.PdfiumCore: mContext may be null 02-20 13:20:44.293 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at com.shockwave.pdfium.PdfiumCore.renderPageBitmap(PdfiumCore.java:229) 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at com.github.barteksc.pdfviewer.RenderingHandler.proceed(RenderingHandler.java:91) 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at com.github.barteksc.pdfviewer.RenderingHandler.handleMessage(RenderingHandler.java:70) 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102) 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.Looper.loop(Looper.java:148) 02-20 13:20:44.294 27742-28133/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.HandlerThread.run(HandlerThread.java:61) 02-20 13:20:44.297 27742-28321/com1.example.abhijeethallur.pdfexample E/com.shockwave.pdfium.PdfiumCore: mContext may be null 02-20 13:20:44.297 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference 02-20 13:20:44.297 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at com.shockwave.pdfium.PdfiumCore.renderPageBitmap(PdfiumCore.java:229) 02-20 13:20:44.298 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at com.github.barteksc.pdfviewer.RenderingHandler.proceed(RenderingHandler.java:91) 02-20 13:20:44.298 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at com.github.barteksc.pdfviewer.RenderingHandler.handleMessage(RenderingHandler.java:70) 02-20 13:20:44.298 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102) 02-20 13:20:44.298 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.Looper.loop(Looper.java:148) 02-20 13:20:44.298 27742-28321/com1.example.abhijeethallur.pdfexample W/System.err: at android.os.HandlerThread.run(HandlerThread.java:61) 02-20 13:20:49.592 27742-27742/com1.example.abhijeethallur.pdfexample I/Choreographer: Skipped 89 frames! The application may be doing too much work on its main thread. 02-20 13:20:57.676 27742-27742/com1.example.abhijeethallur.pdfexample I/Choreographer: Skipped 149 frames! The application may be doing too much work on its main thread.

@barteksc Kindly have a look and let me know if you can help me !!

doubledeath commented 7 years ago

@abhijeethallur, pdfView.load() is heavyweight operation, so i recommend to call it in background thread (now you are loading it on ui, the same as recyclerview thread, so there is laggin' scroll). Additionally you getting nullpointerexceptions is log, that's why you rendering page after view is recycled - to fix this (also often catching exeptions in adapter can cause lags), and to get a working loading in background thread, user my #196 fork, original branch has a bug when it loading from non-ui thread. Try it plz, it may help you.

abhijeethallur commented 7 years ago

Hi @doubledeath , I tried the following method. It wasn't helpful either.

@Override
    public void onViewAttachedToWindow(DataObjectHolder holder) {
        super.onViewAttachedToWindow(holder);

        final DataObjectHolder dh = holder;
        final int pos = holder.getAdapterPosition();

        dh.pdfView.setVisibility(View.GONE);
        dh.pdfView.useBestQuality(false);
        dh.pdfView.enableDoubletap(true);

        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                dh.pdfView.fromAsset(mPdfPathsList.get(pos))
                        .onLoad(new OnLoadCompleteListener() {
                            @Override
                            public void loadComplete(int nbPages) {                            
                                mActivity.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        dh.pdfView.setVisibility(View.VISIBLE);
                                    }
                                });
                            }
                        })
                        .load();
            }
        });
        thread.start();
    }

May be it is taking time to draw the item. Because if I try keeping pdfView visibility to GONE then the scroll is perfect. Only when the item becomes visible then its being drawn and it takes time for heavier pdfs.

doubledeath commented 7 years ago

@abhijeethallur it will take time anyway, output to ui thread will take neccessary time. Additionally causes in your example - you creating a new thread in adapter. Creating a new thread is very heavyweight operation, i guess it's example, in your opinion, but it's also can cause lags when scrolling. Try it one more time using threadpool with, for example, threads similar to count of visible items of adapter (i recommend not more then 4). Additionally, when you render pdf in onViewAttachedToWindow() i guess recyclerview cant correctly recycle views, its also can cause lags. Use onBindViewHolder and try to find out better way to search reason of blank pages. Try to add pages(0) into config of pdfView (you will load only first page, not all).

SiddheshShetye commented 5 years ago

I am also facing same issue. how to load PDF in background?

lubenard commented 3 years ago

Hey ! getting the same problem here !