Adv

Android PDF Reader Examples

The concept is basically reading PDF files from a device and rendering them in a PDFView.

Share

Related Concepts

Adv

1 Example

  1. This is a tutorial about implementing a basic PDF Reader using ListView and third party PDF Rendering library.

    We will list PDF items from external storage into a ListView. When you click a PDF item, a new PDF Reader activity is opened and you can read the PDF with advanced capabilities like zooming, scrolling, swiping and pagination.

    Android PDF Reader ListView

    Android PDF Reader ListView

    Android PDF Reader ListView

    Gradle Scripts

    Given we are using a third party PDF Renderer, we need to add dependencies in the app level build.gradle.

    1. Build.gadle

    • Go over and dependencies. We are using android-pdf-viewer library.
        apply plugin: 'com.android.application'
    
        android {
            compileSdkVersion 24
            buildToolsVersion "24.0.1"
    
            defaultConfig {
                applicationId "com.tutorials.hp.listviewpdf"
                minSdkVersion 15
                targetSdkVersion 24
                versionCode 1
                versionName "1.0"
            }
            buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                }
            }
        }
    
        dependencies {
            compile fileTree(dir: 'libs', include: ['*.jar'])
            testCompile 'junit:junit:4.12'
            compile 'com.android.support:appcompat-v7:24.1.1'
            compile 'com.android.support:design:24.1.1'
            compile 'com.android.support:cardview-v7:24.1.1'
            compile 'com.github.barteksc:android-pdf-viewer:1.4.0'
        }

    LAYOUTS

    We’ll work with 4 layouts:

    1. activity_main.xml

    • Our MainActivity layout.
    • Root layout is CordinatorLayout.
    • This layout defines:
      1. appbar
      2. Toolbar
      3. FloatingActionButton.
    • We also include our content_main.xml here.
        <?xml version="1.0" encoding="utf-8"?>
        <android.support.design.widget.CoordinatorLayout 
            
            
            android_layout_width="match_parent"
            android_layout_height="match_parent"
            android_fitsSystemWindows="true"
            tools_context="com.tutorials.hp.listviewpdf.MainActivity">
    
            <android.support.design.widget.AppBarLayout
                android_layout_width="match_parent"
                android_layout_height="wrap_content"
                android_theme="@style/AppTheme.AppBarOverlay">
    
                <android.support.v7.widget.Toolbar
                    android_id="@+id/toolbar"
                    android_layout_width="match_parent"
                    android_layout_height="?attr/actionBarSize"
                    android_background="?attr/colorPrimary"
                    app_popupTheme="@style/AppTheme.PopupOverlay" />
    
            </android.support.design.widget.AppBarLayout>
    
            <include layout="@layout/content_main" />
    
            <android.support.design.widget.FloatingActionButton
                android_id="@+id/fab"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_layout_gravity="bottom|end"
                android_layout_margin="@dimen/fab_margin"
                android_src="@android:drawable/ic_dialog_email" />
    
        </android.support.design.widget.CoordinatorLayout>

    2. content_main.xml

    • Still part of our MainActivity layout.
    • Root layout is RelativeLayout
    • It gets included inside the activity_main.xml.
    • Will hold our ListView onto which our PDFs will be displayed.
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout 
            
            
            android_layout_width="match_parent"
            android_layout_height="match_parent"
            android_paddingBottom="@dimen/activity_vertical_margin"
            android_paddingLeft="@dimen/activity_horizontal_margin"
            android_paddingRight="@dimen/activity_horizontal_margin"
            android_paddingTop="@dimen/activity_vertical_margin"
            app_layout_behavior="@string/appbar_scrolling_view_behavior"
            tools_context="com.tutorials.hp.listviewpdf.MainActivity"
            tools_showIn="@layout/activity_main">
    
            <ListView
                android_id="@+id/lv"
                android_layout_width="match_parent"
                android_layout_height="wrap_content"
                />
        </RelativeLayout>

    3. model.xml

    • Will model our custom rows for our listview.
    • The listview should contain images and text. The images will be an icon to indicate a PDF. Thus the user knows the list contains PDFs.
    • At the root tag is a .support.v7.widget.CardView.
        <?xml version="1.0" encoding="utf-8"?>
        <android.support.v7.widget.CardView 
            android_orientation="horizontal" android_layout_width="match_parent"
            
            android_layout_margin="10dp"
            card_view_cardCornerRadius="5dp"
            card_view_cardElevation="5dp"
            android_layout_height="200dp">
    
                <LinearLayout
                    android_orientation="horizontal"
                    android_layout_width="match_parent"
                    android_layout_height="match_parent">
    
                    <ImageView
                        android_id="@+id/pdfImage"
                        android_src="@drawable/pdf_icon"
                        android_layout_width="150dp"
                        android_layout_height="wrap_content" />
    
                    <LinearLayout
                        android_orientation="vertical"
                        android_layout_width="wrap_content"
                        android_layout_height="wrap_content">
    
                        <TextView
                            android_layout_width="wrap_content"
                            android_layout_height="wrap_content"
                            android_textAppearance="?android:attr/textAppearanceLarge"
                            android_text="Name"
                            android_id="@+id/nameTxt"
                            android_padding="10dp"
                            android_textColor="@color/colorAccent"
                            android_textStyle="bold"
                            android_layout_alignParentLeft="true"
                            />
    
                    </LinearLayout>
    
                    </LinearLayout>
        </android.support.v7.widget.CardView>

    4. activity_pdf.xml

    • Now this layout will be our PDF render layout.
    • It’s our PDF Viewer layout.
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout 
            
            android_layout_width="match_parent"
            android_layout_height="match_parent"
            android_paddingBottom="@dimen/activity_vertical_margin"
            android_paddingLeft="@dimen/activity_horizontal_margin"
            android_paddingRight="@dimen/activity_horizontal_margin"
            android_paddingTop="@dimen/activity_vertical_margin"
            tools_context="com.tutorials.hp.listviewpdf.PDFActivity">
    
            <com.github.barteksc.pdfviewer.PDFView
                android_id="@+id/pdfView"
                android_layout_width="match_parent"
                android_layout_height="match_parent"
                android_layout_toLeftOf="@+id/scrollBar"/>
    
            <com.github.barteksc.pdfviewer.ScrollBar
                android_id="@+id/scrollBar"
                android_layout_width="wrap_content"
                android_layout_height="match_parent"
                android_layout_alignParentRight="true"
                android_layout_alignParentEnd="true" />
        </RelativeLayout>

    JAVA CLASSES

    Let’s now look at our 4 Java classes.

    1. PDFDoc.java

    This is our data object. Our POJO class.

    POJO stands for Plain Old Java Object. We use this class to represent our data entity. In this case a PDF document.

    This class will hold the PDF’s:

    • name
    • path
        package com.tutorials.hp.listviewpdf;
    
        public class PDFDoc {
            String name,path;
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getPath() {
                return path;
            }
    
            public void setPath(String path) {
                this.path = path;
            }
        }

    2. CustomAdapter.java

    This is our adapter class. It will derive from android.widget.BaseAdapter. This is what makes the class an adapter.

    Then we’ll override a couple of methods given that BaseAdapter is an abstract class.

    An adapter class basically adapts data to custom views. Like in our case we have a ListView with images and text. well that’s a custom listview. So we need the adapter class to help in binding the data to this listview.

    We also handle OnClick event for our ListView here. Hence opening the PDF Activity to view/read the PDF document.

        package com.tutorials.hp.listviewpdf;
    
        import android.content.Context;
        import android.content.Intent;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        import android.widget.BaseAdapter;
        import android.widget.ImageView;
        import android.widget.TextView;
    
        import java.util.ArrayList;
    
        /**
         * Created by Oclemy on 7/28/2016 for ProgrammingWizards Channel and http://www.camposha.com.
         */
        public class CustomAdapter extends BaseAdapter {
    
            Context c;
            ArrayList<PDFDoc> pdfDocs;
    
            public CustomAdapter(Context c, ArrayList<PDFDoc> pdfDocs) {
                this.c = c;
                this.pdfDocs = pdfDocs;
            }
    
            @Override
            public int getCount() {
                return pdfDocs.size();
            }
    
            @Override
            public Object getItem(int i) {
                return pdfDocs.get(i);
            }
    
            @Override
            public long getItemId(int i) {
                return i;
            }
    
            @Override
            public View getView(int i, View view, ViewGroup viewGroup) {
                if(view==null)
                {
                    //INFLATE CUSTOM LAYOUT
                    view= LayoutInflater.from(c).inflate(R.layout.model,viewGroup,false);
                }
    
                final PDFDoc pdfDoc= (PDFDoc) this.getItem(i);
    
                TextView nameTxt= (TextView) view.findViewById(R.id.nameTxt);
                ImageView img= (ImageView) view.findViewById(R.id.pdfImage);
    
                //BIND DATA
                nameTxt.setText(pdfDoc.getName());
                img.setImageResource(R.drawable.pdf_icon);
    
                //VIEW ITEM CLICK
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                       openPDFView(pdfDoc.getPath());
                    }
                });
                return view;
            }
    
            //OPEN PDF VIEW
            private void openPDFView(String path)
            {
                Intent i=new Intent(c,PDFActivity.class);
                i.putExtra("PATH",path);
                c.startActivity(i);
            }
        }

    3. PDFActivity.java

    This is class is an activity because we derive from android.support.v7.app.AppCompatActivity, which is a support version of android.app.activity.

    This class is our PDF Renderer/PDF Viewer. Users will read PDF documents here.

    The first activity(MainActivity) will be responsible for listing pdf documents. This activity, however, will be responsible or viewing them.

        package com.tutorials.hp.listviewpdf;
    
        import android.content.Intent;
        import android.support.v7.app.AppCompatActivity;
        import android.os.Bundle;
        import android.widget.Toast;
    
        import com.github.barteksc.pdfviewer.PDFView;
        import com.github.barteksc.pdfviewer.ScrollBar;
        import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
    
        import java.io.File;
    
        public class PDFActivity extends AppCompatActivity {
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_pdf);
    
                //PDFVIEW SHALL DISPLAY OUR PDFS
                PDFView pdfView= (PDFView) findViewById(R.id.pdfView);
                //SCROLLBAR TO ENABLE SCROLLING
                ScrollBar scrollBar = (ScrollBar) findViewById(R.id.scrollBar);
                pdfView.setScrollBar(scrollBar);
                //VERTICAL SCROLLING
                scrollBar.setHorizontal(false);
                //SACRIFICE MEMORY FOR QUALITY
                //pdfView.useBestQuality(true)
    
                //UNPACK OUR DATA FROM INTENT
                Intent i=this.getIntent();
                String path=i.getExtras().getString("PATH");
    
                //GET THE PDF FILE
                File file=new File(path);
    
                if(file.canRead())
                {
                    //LOAD IT
                    pdfView.fromFile(file).defaultPage(1).onLoad(new OnLoadCompleteListener() {
                        @Override
                        public void loadComplete(int nbPages) {
                            Toast.makeText(PDFActivity.this, String.valueOf(nbPages), Toast.LENGTH_LONG).show();
                        }
                    }).load();
    
                }
    
            }
        }

    4. MainActivity.java

    This is our launcher activity. This means when the app is run it is this activity that gets executed by default.

    This class derives from android.support.v7.app.AppCompatActivity.

    We proceed and override the OnCreate(0 method.

    We will read our android external storage to obtain PDF documents from downloads directory here.

    We will then list these pdf documents in the mainactivity.

        package com.tutorials.hp.listviewpdf;
    
        import android.os.Bundle;
        import android.os.Environment;
        import android.support.design.widget.FloatingActionButton;
        import android.support.v7.app.AppCompatActivity;
        import android.support.v7.widget.Toolbar;
        import android.view.View;
        import android.widget.ListView;
    
        import java.io.File;
        import java.util.ArrayList;
    
        public class MainActivity extends AppCompatActivity {
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
                setSupportActionBar(toolbar);
                final ListView lv= (ListView) findViewById(R.id.lv);
    
                FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
                fab.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        lv.setAdapter(new CustomAdapter(MainActivity.this,getPDFs()));
    
                    }
                });
            }
    
            private ArrayList<PDFDoc> getPDFs()
    
            {
                ArrayList<PDFDoc> pdfDocs=new ArrayList<>();
                //TARGET FOLDER
                File downloadsFolder= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    
                PDFDoc pdfDoc;
    
                if(downloadsFolder.exists())
                {
                    //GET ALL FILES IN DOWNLOAD FOLDER
                    File[] files=downloadsFolder.listFiles();
    
                    //LOOP THRU THOSE FILES GETTING NAME AND URI
                    for (int i=0;i<files.length;i++)
                    {
                        File file=files[i];
    
                        if(file.getPath().endsWith("pdf"))
                        {
                            pdfDoc=new PDFDoc();
                            pdfDoc.setName(file.getName());
                            pdfDoc.setPath(file.getAbsolutePath());
    
                            pdfDocs.add(pdfDoc);
                        }
    
                    }
                }
    
                return pdfDocs;
            }
        }

    AndroidManifest.xml

    Add this permission in your androidmanifest:

    <uses-permission android_name="android.permission.READ_EXTERNAL_STORAGE" />

     

    Download

    Download code below.

    Download the source code here.

     




Share an Example

Share an Example

Browse
What is the capital of Egypt? ( Cairo )