>) wrapper -> {
51 | if ((wrapper.throwable instanceof ConnectException
52 | || wrapper.throwable instanceof SocketTimeoutException
53 | || wrapper.throwable instanceof TimeoutException)
54 | && wrapper.index < count + 1) { //如果超出重试次数也抛出错误,否则默认是会进入onCompleted
55 | Log.e("tag","retry---->"+wrapper.index);
56 | return Observable.timer(delay + (wrapper.index - 1) * increaseDelay, TimeUnit.MILLISECONDS);
57 |
58 | }
59 | return Observable.error(wrapper.throwable);
60 | });
61 | }
62 |
63 | private class Wrapper {
64 | private int index;
65 | private Throwable throwable;
66 |
67 | public Wrapper(Throwable throwable, int index) {
68 | this.index = index;
69 | this.throwable = throwable;
70 | }
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/CircleProgressBar.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Rect;
9 | import android.graphics.RectF;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 |
13 | /**
14 | * @author xiaolong
15 | * @version v1.0
16 | * @function <描述功能>
17 | * @date 2017/2/10-11:02
18 | */
19 | public class CircleProgressBar extends View {
20 | private int width;// 控件的宽度
21 | private int height;// 控件的高度
22 | private int radius;// 圆形的半径
23 | private int socktwidth = dp2px(8);// 圆环进度条的宽度
24 | private Paint paint = new Paint();
25 | private Rect rec = new Rect();
26 | private int value = 70;// 百分比0~100;
27 | private int textSize = dp2px(18);// 文字大小
28 | private Bitmap bitmap;
29 | @Deprecated
30 | float scale = 0.15f;// 中间背景图片相对圆环的大小的比例
31 | private int preColor = Color.parseColor("#2c2200");// 进度条未完成的颜色
32 | private int progressColor = Color.parseColor("#6bb849");// 进度条颜色
33 | private float paddingscale = 0.8f;// 控件内偏距占空间本身的比例
34 | private int CircleColor = Color.parseColor("#CCCCCC");// 圆中间的背景颜色
35 | private int textColor = progressColor;// 文字颜色
36 | private onProgressListener monProgress;// 进度时间监听
37 | private int startAngle = 270;
38 | RectF rectf = new RectF();
39 |
40 | public CircleProgressBar(Context context, AttributeSet attrs) {
41 | super(context, attrs);
42 | }
43 |
44 | @Override
45 | protected void onDraw(Canvas canvas) {
46 | width = getWidth();
47 | int size = height = getHeight();
48 | if (height > width)
49 | size = width;
50 | radius = (int) (size * paddingscale / 2f);
51 | paint.setAntiAlias(true);
52 | paint.setColor(progressColor);
53 | // 绘制最大的圆 进度条圆环的背景颜色(未走到的进度)就是这个哦
54 | canvas.drawCircle(width / 2, height / 2, radius, paint);
55 | paint.setColor(preColor);
56 | canvas.drawCircle(width / 2, height / 2, radius-1, paint);
57 | rectf.set((width - radius * 2) / 2f, (height - radius * 2) / 2f,
58 | ((width - radius * 2) / 2f) + (2 * radius),
59 | ((height - radius * 2) / 2f) + (2 * radius));
60 | paint.setColor(progressColor);
61 | canvas.drawArc(rectf, startAngle, value * 3.6f, true, paint);
62 | paint.setColor(CircleColor);
63 | // 绘制用于遮住伞形两个边的小圆
64 | canvas.drawCircle(width / 2, height / 2, radius - socktwidth, paint);
65 | if (bitmap != null) {// 绘制中间的图片
66 | int width2 = (int) (rectf.width() * scale);
67 | int height2 = (int) (rectf.height() * scale);
68 | rectf.set(rectf.left + width2, rectf.top + height2, rectf.right
69 | - width2, rectf.bottom - height2);
70 | canvas.drawBitmap(bitmap, null, rectf, null);
71 | }
72 | String v = value + "%";
73 | paint.setColor(textColor);
74 | paint.setTextSize(textSize);
75 | paint.getTextBounds(v, 0, v.length(), rec);
76 | int textwidth = rec.width();
77 | int textheight = rec.height();
78 | // 绘制中间文字
79 | canvas.drawText(v, (width - textwidth) / 2,
80 | ((height + textheight) / 2), paint);
81 | super.onDraw(canvas);
82 | }
83 |
84 | public int dp2px(int dp) {
85 | return (int) ((getResources().getDisplayMetrics().density * dp) + 0.5);
86 | }
87 |
88 | /**
89 | * 设置进度
90 | *
91 | * @param value
92 | * ps: 百分比 0~100;
93 | */
94 | public void setValue(int value) {
95 | if (value > 100)
96 | return;
97 | this.value = value;
98 | invalidate();
99 | if (monProgress != null)
100 | monProgress.onProgress(value);
101 | }
102 |
103 | /**
104 | * 设置圆环进度条的宽度 px
105 | */
106 | public CircleProgressBar setProdressWidth(int width) {
107 | this.socktwidth = width;
108 | return this;
109 | }
110 |
111 | /**
112 | * 设置文字大小
113 | *
114 | * @param value
115 | */
116 | public CircleProgressBar setTextSize(int value) {
117 | textSize = value;
118 | return this;
119 | }
120 |
121 | /**
122 | * 设置文字大小
123 | */
124 | public CircleProgressBar setTextColor(int color) {
125 | this.textColor = color;
126 | return this;
127 | }
128 |
129 | /**
130 | * 设置进度条之前的颜色
131 | */
132 | public CircleProgressBar setPreProgress(int precolor) {
133 | this.preColor = precolor;
134 | return this;
135 | }
136 |
137 | /**
138 | * 设置进度颜色
139 | *
140 | * @param color
141 | */
142 | public CircleProgressBar setProgress(int color) {
143 | this.progressColor = color;
144 | return this;
145 | }
146 |
147 | /**
148 | * 设置圆心中间的背景颜色
149 | *
150 | * @param color
151 | * @return
152 | */
153 | public CircleProgressBar setCircleBackgroud(int color) {
154 | this.CircleColor = color;
155 | return this;
156 | }
157 |
158 | /**
159 | * 设置圆相对整个控件的宽度或者高度的占用比例
160 | *
161 | * @param scale
162 | */
163 | public CircleProgressBar setPaddingscale(float scale) {
164 | this.paddingscale = scale;
165 | return this;
166 | }
167 |
168 | /**
169 | * 设置开始的位置
170 | *
171 | * @param startAngle 0~360
172 | *
173 | * ps 0代表在最右边 90 最下方 按照然后顺时针旋转
174 | */
175 | public CircleProgressBar setStartAngle(int startAngle) {
176 | this.startAngle = startAngle;
177 | return this;
178 | }
179 |
180 | public interface onProgressListener {
181 | void onProgress(int value);
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/PDFManager.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.net.Uri;
6 | import android.util.Log;
7 |
8 | import com.shockwave.pdfium.PdfDocument;
9 | import com.shockwave.pdfium.PdfiumCore;
10 |
11 | import java.io.File;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.util.List;
15 |
16 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.AssetSource;
17 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.ByteArraySource;
18 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.DocumentSource;
19 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.FileSource;
20 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.InputStreamSource;
21 | import cn.xiaolong.pdfiumpdfviewer.pdf.source.UriSource;
22 | import rx.Observable;
23 | import rx.schedulers.Schedulers;
24 | //参照着读取文件流的封装。如果想要把manager这个类变得可扩展,
25 | // 比如说后面我们添加了DocManager..等等图片生成的Manager
26 | //这个时候就应该把用到的方法抽出来,图片生成的方法,资源回收的方法等。
27 | // 获取总数的方法抽到某个interface/父类中去,通过继承还有接口实现来达到目的。
28 | // 到那时候就可以直接使用父类的Manager来指定自己需要实例化的对象。
29 | //这也正是封装,继承和多态的妙处
30 |
31 | /**
32 | * @author xiaolong
33 | * @version v1.0
34 | * @function <描述功能>
35 | * @date 2017/2/27-17:15
36 | */
37 | public class PDFManager {
38 | private static String TAG = "PDF";
39 | private Context mContext;
40 | private PdfiumCore mPdfiumCore;
41 | private PdfDocument mPdfDocument;
42 | private int pageCount;
43 | private int realWidth = 0;
44 | private int realHeight = 0;
45 |
46 | private PDFManager(Context context, DocumentSource documentSource, String password,
47 | OnOpenErrorListener onErrorListener, OnOpenSuccessListener onOpenSuccessListener) {
48 | mContext = context;
49 | mPdfiumCore = new PdfiumCore(context);
50 | try {
51 | mPdfDocument = documentSource.createDocument(context, mPdfiumCore, password);
52 | pageCount = mPdfiumCore.getPageCount(mPdfDocument);
53 | if (onOpenSuccessListener != null)
54 | onOpenSuccessListener.onSuccess();
55 | } catch (IOException e) {
56 | e.printStackTrace();
57 | Log.e(TAG, "PDF Couldn't Open");
58 | if (onErrorListener != null)
59 | onErrorListener.onError(e.getCause());
60 | }
61 |
62 | }
63 |
64 | public Observable getPdfBitmapNormalSize(final int pageIndex) {
65 | return Observable.create((Observable.OnSubscribe) subscriber -> {
66 | mPdfiumCore.openPage(mPdfDocument, pageIndex);
67 | if (realWidth == 0) {
68 | realWidth = mPdfiumCore.getPageWidthPoint(mPdfDocument, pageIndex);
69 | realHeight = mPdfiumCore.getPageHeightPoint(mPdfDocument, pageIndex);
70 | }
71 | Bitmap bitmap = Bitmap.createBitmap(realWidth * 2, realHeight * 2,
72 | Bitmap.Config.ARGB_8888);
73 | mPdfiumCore.renderPageBitmap(mPdfDocument, bitmap, pageIndex, 0, 0,
74 | realWidth, realWidth);
75 | subscriber.onNext(bitmap);
76 | subscriber.onCompleted();
77 | }).subscribeOn(Schedulers.io());
78 |
79 |
80 | // printInfo(mPdfiumCore, mPdfDocument);
81 | // return Observable.just(bitmap);
82 | }
83 |
84 | public Observable getPdfBitmapCustomSize(final int pageIndex, final int width) {
85 | return Observable.create((Observable.OnSubscribe) subscriber -> {
86 | mPdfiumCore.openPage(mPdfDocument, pageIndex);
87 | if (realWidth == 0) {
88 | realWidth = mPdfiumCore.getPageWidthPoint(mPdfDocument, pageIndex);
89 | realHeight = mPdfiumCore.getPageHeightPoint(mPdfDocument, pageIndex);
90 | }
91 | int height = (realHeight * width) / realWidth;
92 | Bitmap bitmap = Bitmap.createBitmap(width, height,
93 | Bitmap.Config.ARGB_8888);
94 | mPdfiumCore.renderPageBitmap(mPdfDocument, bitmap, pageIndex, 0, 0,
95 | width, height);
96 | subscriber.onNext(bitmap);
97 | subscriber.onCompleted();
98 | }).subscribeOn(Schedulers.io());
99 |
100 | // printInfo(mPdfiumCore, mPdfDocument);
101 | }
102 |
103 | public int pageCount() {
104 | return pageCount;
105 | }
106 |
107 | /**
108 | * this must do when all work have done, to recycle the memory
109 | */
110 | public void recycle() {
111 | if (mPdfDocument != null) {
112 | mPdfiumCore.closeDocument(mPdfDocument); // important!
113 | }
114 | }
115 |
116 | public void printInfo(PdfiumCore core, PdfDocument doc) {
117 | PdfDocument.Meta meta = core.getDocumentMeta(doc);
118 | Log.e(TAG, "title = " + meta.getTitle());
119 | Log.e(TAG, "author = " + meta.getAuthor());
120 | Log.e(TAG, "subject = " + meta.getSubject());
121 | Log.e(TAG, "keywords = " + meta.getKeywords());
122 | Log.e(TAG, "creator = " + meta.getCreator());
123 | Log.e(TAG, "producer = " + meta.getProducer());
124 | Log.e(TAG, "creationDate = " + meta.getCreationDate());
125 | Log.e(TAG, "modDate = " + meta.getModDate());
126 |
127 | printBookmarksTree(core.getTableOfContents(doc), "-");
128 |
129 | }
130 |
131 | public void printBookmarksTree(List tree, String sep) {
132 | for (PdfDocument.Bookmark b : tree) {
133 |
134 | Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
135 |
136 | if (b.hasChildren()) {
137 | printBookmarksTree(b.getChildren(), sep + "-");
138 | }
139 | }
140 | }
141 |
142 | public static class Builder {
143 | private DocumentSource mDocumentSource;
144 | private Context context;
145 | private String password;
146 | private OnOpenErrorListener mOnErrorListener;
147 | private OnOpenSuccessListener mOnOpenSuccessListener;
148 | private static final int KILOBYTE = 1024;
149 | private static final int BUFFER_LEN = 1 * KILOBYTE;
150 | private static final int NOTIFY_PERIOD = 150 * KILOBYTE;
151 |
152 | public Builder(Context context) {
153 | this.context = context;
154 | }
155 |
156 | public Builder pdfFromFile(File file) {
157 | mDocumentSource = new FileSource(file);
158 | return this;
159 | }
160 |
161 | public Builder pdfFromStream(InputStream inputStream) {
162 | mDocumentSource = new InputStreamSource(inputStream);
163 | return this;
164 | }
165 |
166 | public Builder pdfFromUri(Uri uri) {
167 | mDocumentSource = new UriSource(uri);
168 | return this;
169 | }
170 |
171 | public Builder pdfFormAsset(String assetName) {
172 | mDocumentSource = new AssetSource(assetName);
173 | return this;
174 | }
175 |
176 | public Builder pdfFromByte(byte[] data) {
177 | mDocumentSource = new ByteArraySource(data);
178 | return this;
179 | }
180 |
181 | public Builder setPassword(String password) {
182 | this.password = password;
183 | return this;
184 | }
185 |
186 | public Builder setOnOpenErrorListener(OnOpenErrorListener onErrorListener) {
187 | this.mOnErrorListener = onErrorListener;
188 | return this;
189 | }
190 |
191 | public Builder setOnOpenSuccessListener(OnOpenSuccessListener onOpenSuccessListener) {
192 | this.mOnOpenSuccessListener = onOpenSuccessListener;
193 | return this;
194 | }
195 |
196 | public PDFManager build() {
197 | return new PDFManager(context, mDocumentSource, password, mOnErrorListener, mOnOpenSuccessListener);
198 | }
199 | }
200 |
201 | public interface OnOpenErrorListener {
202 | /**
203 | * Called if error occurred while opening PDF
204 | *
205 | * @param t Throwable with error
206 | */
207 | void onError(Throwable t);
208 | }
209 |
210 | public interface OnOpenSuccessListener {
211 | void onSuccess();
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/PhotoViewPager.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 |
8 | /**
9 | * @author xiaolong
10 | * @version v1.0
11 | * @function
12 | * @date 2017/2/28-16:41
13 | */
14 | public class PhotoViewPager extends ViewPager {
15 | public PhotoViewPager(Context context) {
16 | super(context);
17 | }
18 |
19 | public PhotoViewPager(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | }
22 |
23 | @Override
24 | public boolean onInterceptTouchEvent(MotionEvent ev) {
25 | try {
26 | return super.onInterceptTouchEvent(ev);
27 | } catch (IllegalArgumentException e) {
28 | e.printStackTrace();
29 | } catch (ArrayIndexOutOfBoundsException e) {
30 | e.printStackTrace();
31 | }
32 | return false;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/adapter/PdfGuideAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 |
12 | import java.util.concurrent.ConcurrentHashMap;
13 |
14 | import cn.xiaolong.pdfiumpdfviewer.R;
15 | import cn.xiaolong.pdfiumpdfviewer.pdf.PDFManager;
16 | import cn.xiaolong.pdfiumpdfviewer.pdf.list.ViewHolder;
17 | import rx.Observable;
18 | import rx.Subscriber;
19 | import rx.android.schedulers.AndroidSchedulers;
20 |
21 |
22 | /**
23 | * @author xiaolong
24 | * @version v1.0
25 | * @function <左侧列表适配器>
26 | * @date 2017/2/27-14:50
27 | */
28 | public class PdfGuideAdapter extends BaseAdapter {
29 |
30 | private PDFManager mPdfManager;
31 | private Context mContext;
32 | private ConcurrentHashMap mConcurrentHashMap;
33 | private View.OnClickListener mOnItemClickListener;
34 | private int[] mStates;
35 | private int count;
36 |
37 | public PdfGuideAdapter(Context context, PDFManager pdfManager) {
38 | this.mPdfManager = pdfManager;
39 | this.mContext = context;
40 | mConcurrentHashMap = new ConcurrentHashMap();
41 | count = mPdfManager.pageCount();
42 | mStates = new int[count];
43 | }
44 |
45 | @Override
46 | public int getCount() {
47 | return mPdfManager.pageCount();
48 | }
49 |
50 | @Override
51 | public Object getItem(int position) {
52 | // return mPdfManager.getPdfBitmapNormalSize(position);
53 | return "sb";
54 | }
55 |
56 | public void setOnItemClickListener(View.OnClickListener onItemClickListener) {
57 | mOnItemClickListener = onItemClickListener;
58 | }
59 |
60 | @Override
61 | public long getItemId(int position) {
62 | return position;
63 | }
64 |
65 | @Override
66 | public View getView(final int position, View convertView, ViewGroup parent) {
67 | ViewHolder viewHolder = ViewHolder.get(mContext, convertView, parent,
68 | R.layout.listitem_guide, position);
69 | TextView tvGuideName = viewHolder.getView(R.id.tvLocate);
70 | final ImageView imageView = viewHolder.getView(R.id.imageView);
71 | getBitmap(position).observeOn(AndroidSchedulers.mainThread()).subscribeOn(AndroidSchedulers.mainThread())
72 | .subscribe(new Subscriber() {
73 | @Override
74 | public void onStart() {
75 | super.onStart();
76 | // imageView.setImageResource(R.drawable.ic_delete);
77 | }
78 |
79 | @Override
80 | public void onCompleted() {
81 | // Log.d("adapterloadCompleted","completed");
82 |
83 | }
84 |
85 | @Override
86 | public void onError(Throwable e) {
87 | // Log.d("adapterError",e.getMessage());
88 | }
89 |
90 | @Override
91 | public void onNext(Bitmap bitmap) {
92 | imageView.setImageBitmap(bitmap);
93 | }
94 | });
95 | tvGuideName.setText(position + 1 + "");
96 | if (mStates[position] == 1) {
97 | imageView.setSelected(true);
98 | } else {
99 | imageView.setSelected(false);
100 | }
101 | if (mOnItemClickListener != null) {
102 | imageView.setOnClickListener(v -> {
103 | v.setTag(position);
104 | mOnItemClickListener.onClick(v);
105 | viewHolder.getConvertView().setSelected(false);
106 | setStatePosition(position);
107 | });
108 | }
109 | return viewHolder.getConvertView();
110 | }
111 |
112 | public Observable getBitmap(final int position) {
113 | return mConcurrentHashMap.get(position) == null ?
114 | mPdfManager.getPdfBitmapCustomSize(position, 160)
115 | .doOnNext(bitmap -> mConcurrentHashMap.put(position, bitmap)) : Observable.just(mConcurrentHashMap.get(position));
116 | }
117 |
118 | public void setStatePosition(int position) {
119 | mStates = new int[count];
120 | mStates[position] = 1;
121 | notifyDataSetChanged();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/adapter/PdfImageAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.support.v4.view.PagerAdapter;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 |
11 | import cn.xiaolong.pdfiumpdfviewer.R;
12 | import cn.xiaolong.pdfiumpdfviewer.pdf.PDFManager;
13 | import cn.xiaolong.pdfiumpdfviewer.pdf.utils.ScreenUtil;
14 | import rx.Subscriber;
15 | import rx.android.schedulers.AndroidSchedulers;
16 | import uk.co.senab.photoview.PhotoView;
17 |
18 | /**
19 | * @author xiaolong
20 | * @version v1.0
21 | * @function
22 | * @date 2016/7/18-16:57
23 | */
24 | public class PdfImageAdapter extends PagerAdapter {
25 | private Context context;
26 | private PDFManager mPDFManager;
27 |
28 | public PdfImageAdapter(Context context, PDFManager pdfManager) {
29 | this.context = context;
30 | mPDFManager = pdfManager;
31 | }
32 |
33 | @Override
34 | public void destroyItem(ViewGroup container, int position, Object object) {
35 | container.removeView((View) object);
36 | Log.d("msg", "page" + (position + 1) + "destory");
37 | }
38 |
39 |
40 | @Override
41 | public int getCount() {
42 | return mPDFManager.pageCount();
43 | }
44 |
45 |
46 | @Override
47 | public Object instantiateItem(ViewGroup container, int position) {
48 | View contentView = View.inflate(context, R.layout.item_viewpage_image, null);
49 | final PhotoView ivLargeImage = (PhotoView) contentView.findViewById(R.id.ivLargeImage);
50 | mPDFManager.getPdfBitmapCustomSize(position, ScreenUtil.getScreenSize(context)[0] * 7 / 8)
51 | .observeOn(AndroidSchedulers.mainThread())
52 | .subscribe(new Subscriber() {
53 | @Override
54 | public void onStart() {
55 | ivLargeImage.setImageResource(R.mipmap.ic_launcher);
56 | }
57 |
58 | @Override
59 | public void onCompleted() {
60 | // Log.d("adapterloadCompleted", "completed");
61 | }
62 |
63 | @Override
64 | public void onError(Throwable e) {
65 | }
66 |
67 | @Override
68 | public void onNext(Bitmap bitmap) {
69 | ivLargeImage.setImageBitmap(bitmap);
70 | }
71 | });
72 | container.addView(contentView);
73 | return contentView;
74 | }
75 |
76 | @Override
77 | public boolean isViewFromObject(View arg0, Object arg1) {
78 | return arg0 == arg1;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/list/ViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf.list;
2 |
3 | import android.content.Context;
4 | import android.util.SparseArray;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | public class ViewHolder
10 | {
11 | private final SparseArray mViews;
12 | private View mConvertView;
13 |
14 | private ViewHolder(Context context, ViewGroup parent, int layoutId,
15 | int position)
16 | {
17 | this.mViews = new SparseArray();
18 | mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,
19 | false);
20 | //setTag
21 | mConvertView.setTag(this);
22 | }
23 |
24 | /**
25 | * 拿到一个ViewHolder对象
26 | * @param context
27 | * @param convertView
28 | * @param parent
29 | * @param layoutId
30 | * @param position
31 | * @return
32 | */
33 | public static ViewHolder get(Context context, View convertView,
34 | ViewGroup parent, int layoutId, int position)
35 | {
36 |
37 | if (convertView == null)
38 | {
39 | return new ViewHolder(context, parent, layoutId, position);
40 | }
41 | return (ViewHolder) convertView.getTag();
42 | }
43 |
44 |
45 | /**
46 | * 通过控件的Id获取对于的控件,如果没有则加入views
47 | * @param viewId
48 | * @return
49 | */
50 | public T getView(int viewId)
51 | {
52 |
53 | View view = mViews.get(viewId);
54 | if (view == null)
55 | {
56 | view = mConvertView.findViewById(viewId);
57 | mViews.put(viewId, view);
58 | }
59 | return (T) view;
60 | }
61 |
62 | public View getConvertView()
63 | {
64 | return mConvertView;
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/AssetSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 |
19 | import android.content.Context;
20 | import android.os.ParcelFileDescriptor;
21 |
22 | import com.shockwave.pdfium.PdfDocument;
23 | import com.shockwave.pdfium.PdfiumCore;
24 |
25 | import java.io.File;
26 | import java.io.IOException;
27 |
28 | import cn.xiaolong.pdfiumpdfviewer.pdf.utils.FileUtils;
29 |
30 | public class AssetSource implements DocumentSource {
31 |
32 | private final String assetName;
33 |
34 | public AssetSource(String assetName) {
35 | this.assetName = assetName;
36 | }
37 |
38 | @Override
39 | public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
40 | File f = FileUtils.fileFromAsset(context, assetName);
41 | ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
42 | return core.newDocument(pfd, password);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/ByteArraySource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 | import android.content.Context;
19 |
20 | import com.shockwave.pdfium.PdfDocument;
21 | import com.shockwave.pdfium.PdfiumCore;
22 |
23 | import java.io.IOException;
24 |
25 | public class ByteArraySource implements DocumentSource {
26 |
27 | private byte[] data;
28 |
29 | public ByteArraySource(byte[] data) {
30 | this.data = data;
31 | }
32 |
33 | @Override
34 | public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
35 | return core.newDocument(data, password);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/DocumentSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 | import android.content.Context;
19 |
20 | import com.shockwave.pdfium.PdfDocument;
21 | import com.shockwave.pdfium.PdfiumCore;
22 |
23 | import java.io.IOException;
24 |
25 | public interface DocumentSource {
26 | PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException;
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/FileSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 | import android.content.Context;
19 | import android.os.ParcelFileDescriptor;
20 |
21 | import com.shockwave.pdfium.PdfDocument;
22 | import com.shockwave.pdfium.PdfiumCore;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 |
27 | public class FileSource implements DocumentSource {
28 |
29 | private File file;
30 |
31 | public FileSource(File file) {
32 | this.file = file;
33 | }
34 |
35 | @Override
36 | public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
37 | ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
38 | return core.newDocument(pfd, password);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/InputStreamSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 | import android.content.Context;
19 |
20 | import com.shockwave.pdfium.PdfDocument;
21 | import com.shockwave.pdfium.PdfiumCore;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 |
26 | import cn.xiaolong.pdfiumpdfviewer.pdf.utils.Util;
27 |
28 | public class InputStreamSource implements DocumentSource {
29 |
30 | private InputStream inputStream;
31 |
32 | @Override
33 | public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
34 | return core.newDocument(Util.toByteArray(inputStream), password);
35 | }
36 |
37 | public InputStreamSource(InputStream inputStream) {
38 | this.inputStream = inputStream;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/source/UriSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.source;
17 |
18 | import android.content.Context;
19 | import android.net.Uri;
20 | import android.os.ParcelFileDescriptor;
21 |
22 | import com.shockwave.pdfium.PdfDocument;
23 | import com.shockwave.pdfium.PdfiumCore;
24 |
25 | import java.io.IOException;
26 |
27 | public class UriSource implements DocumentSource {
28 |
29 | private Uri uri;
30 |
31 | public UriSource(Uri uri) {
32 | this.uri = uri;
33 | }
34 |
35 | @Override
36 | public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
37 | ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
38 | return core.newDocument(pfd, password);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/utils/DownloadFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Olmo Gallegos Hernández.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.utils;
17 |
18 | public interface DownloadFile {
19 | void download(String url, String destinationPath);
20 | void reload();
21 | interface DownloadListener {
22 | void onSuccess(String url, String destinationPath);
23 |
24 | void onFailure(Exception e);
25 |
26 | void onProgressUpdate(int progress, int total);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/utils/DownloadFileUrlConnectionImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Olmo Gallegos Hernández.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.utils;
17 |
18 | import android.content.Context;
19 | import android.os.Handler;
20 | import android.util.Log;
21 |
22 | import java.io.BufferedInputStream;
23 | import java.io.File;
24 | import java.io.FileOutputStream;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.net.HttpURLConnection;
28 | import java.net.MalformedURLException;
29 | import java.net.URL;
30 |
31 | public class DownloadFileUrlConnectionImpl implements DownloadFile {
32 | private static final int KILOBYTE = 1024;
33 |
34 | private static final int BUFFER_LEN = 1 * KILOBYTE;
35 | private static final int NOTIFY_PERIOD = 150 * KILOBYTE;
36 |
37 | Context context;
38 | Handler uiThread;
39 | DownloadListener listener;
40 | private String mUrl = "";
41 | private String mFilePath = "";
42 |
43 | public DownloadFileUrlConnectionImpl(Context context, Handler uiThread, DownloadListener listener) {
44 | this.context = context;
45 | this.uiThread = uiThread;
46 | this.listener = listener;
47 | }
48 |
49 | @Override
50 | public void download(final String url, final String destinationPath) {
51 | if (mUrl.equals("") || mFilePath.equals("")) {
52 | this.mUrl = url;
53 | this.mFilePath = destinationPath;
54 | }
55 | new Thread(() -> {
56 | try {
57 | File file = new File(destinationPath);
58 | FileOutputStream fileOutput = new FileOutputStream(file);
59 | HttpURLConnection urlConnection = null;
60 | URL urlObj = new URL(url);
61 | urlConnection = (HttpURLConnection) urlObj.openConnection();
62 | int totalSize = urlConnection.getContentLength();
63 | int downloadedSize = 0;
64 | int counter = 0;
65 | byte[] buffer = new byte[BUFFER_LEN];
66 | int bufferLength = 0;
67 | InputStream in = new BufferedInputStream(urlConnection.getInputStream());
68 |
69 | while ((bufferLength = in.read(buffer)) > 0) {
70 | fileOutput.write(buffer, 0, bufferLength);
71 | downloadedSize += bufferLength;
72 | notifyProgressOnUiThread(downloadedSize, totalSize);
73 | }
74 |
75 | urlConnection.disconnect();
76 | fileOutput.close();
77 | notifySuccessOnUiThread(url, destinationPath);
78 | } catch (MalformedURLException e) {
79 | notifyFailureOnUiThread(e);
80 | } catch (IOException e) {
81 | notifyFailureOnUiThread(e);
82 | }
83 |
84 | }).start();
85 | }
86 |
87 | @Override
88 | public void reload() {
89 | download(mUrl, mFilePath);
90 | }
91 |
92 | protected void notifySuccessOnUiThread(final String url, final String destinationPath) {
93 | if (uiThread == null) {
94 | return;
95 | }
96 | Log.e("DownLoad", "Success:" + url + " " + destinationPath);
97 | uiThread.post(() -> listener.onSuccess(url, destinationPath));
98 | }
99 |
100 | protected void notifyFailureOnUiThread(final Exception e) {
101 | if (uiThread == null) {
102 | return;
103 | }
104 | Log.e("DownLoad", "Fail:" + e.toString());
105 | uiThread.post(() -> listener.onFailure(e));
106 | }
107 |
108 | private void notifyProgressOnUiThread(final int downloadedSize, final int totalSize) {
109 | if (uiThread == null) {
110 | return;
111 | }
112 |
113 | uiThread.post(() -> listener.onProgressUpdate(downloadedSize, totalSize));
114 | }
115 |
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2016 Bartosz Schiller
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.utils;
17 |
18 | import android.content.Context;
19 | import android.util.Log;
20 |
21 | import java.io.File;
22 | import java.io.FileInputStream;
23 | import java.io.FileNotFoundException;
24 | import java.io.FileOutputStream;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.OutputStream;
28 |
29 | public class FileUtils {
30 | private static final int KILOBYTE = 1024;
31 |
32 | private static final int BUFFER_LEN = 1 * KILOBYTE;
33 | private static final int NOTIFY_PERIOD = 150 * KILOBYTE;
34 |
35 | private FileUtils() {
36 | // Prevents instantiation
37 | }
38 |
39 | public static File fileFromAsset(Context context, String assetName) throws IOException {
40 | File outFile = new File(context.getCacheDir(), assetName + "-pdfview.pdf");
41 | if (assetName.contains("/")) {
42 | outFile.getParentFile().mkdirs();
43 | }
44 | copy(context.getAssets().open(assetName), outFile);
45 | return outFile;
46 | }
47 |
48 | public static void copy(InputStream inputStream, File output) throws IOException {
49 | OutputStream outputStream = null;
50 | try {
51 | outputStream = new FileOutputStream(output);
52 | int read = 0;
53 | byte[] bytes = new byte[1024];
54 | while ((read = inputStream.read(bytes)) != -1) {
55 | outputStream.write(bytes, 0, read);
56 | }
57 | } finally {
58 | try {
59 | if (inputStream != null) {
60 | inputStream.close();
61 | }
62 | } finally {
63 | if (outputStream != null) {
64 | outputStream.close();
65 | }
66 | }
67 | }
68 | }
69 |
70 | public static String extractFileNameFromURL(String url) {
71 | return url.substring(url.lastIndexOf('/') + 1);
72 | }
73 |
74 | /**
75 | * 获取指定文件大小
76 | *
77 | * @return
78 | * @throws Exception
79 | */
80 | public static long getFileSize(File file) {
81 | long size = 0;
82 | try {
83 | if (file.exists()) {
84 | FileInputStream fis = null;
85 | fis = new FileInputStream(file);
86 | size = fis.available();
87 | } else {
88 | file.createNewFile();
89 | Log.e("获取文件大小", "文件不存在!");
90 | }
91 | } catch (FileNotFoundException e) {
92 | e.printStackTrace();
93 | } catch (IOException e) {
94 | e.printStackTrace();
95 | }
96 | return size;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/utils/ScreenUtil.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer.pdf.utils;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.view.Display;
6 | import android.view.WindowManager;
7 |
8 | /**
9 | * @author xiaolong
10 | * @version v1.0
11 | * @function <描述功能>
12 | * @date 2017/3/1-16:55
13 | */
14 | public class ScreenUtil {
15 |
16 | public static int[] getScreenSize(Context context) {
17 |
18 | int[] size = new int[2];
19 |
20 | WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
21 | Display d = w.getDefaultDisplay();
22 | DisplayMetrics metrics = new DisplayMetrics();
23 | d.getMetrics(metrics);
24 | // since SDK_INT = 1;
25 | int widthPixels = metrics.widthPixels;
26 | int heightPixels = metrics.heightPixels;
27 | size[0] = widthPixels;
28 | size[1] = heightPixels /*- getStatusBarHeight(context)*/;
29 | return size;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/cn/xiaolong/pdfiumpdfviewer/pdf/utils/Util.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bartosz Schiller.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package cn.xiaolong.pdfiumpdfviewer.pdf.utils;
17 |
18 | import android.content.Context;
19 | import android.util.TypedValue;
20 |
21 | import java.io.ByteArrayOutputStream;
22 | import java.io.IOException;
23 | import java.io.InputStream;
24 |
25 | public class Util {
26 | private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
27 |
28 | public static int getDP(Context context, int dp) {
29 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
30 | }
31 |
32 | public static byte[] toByteArray(InputStream inputStream) throws IOException {
33 | ByteArrayOutputStream os = new ByteArrayOutputStream();
34 | byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
35 | int n;
36 | while (-1 != (n = inputStream.read(buffer))) {
37 | os.write(buffer, 0, n);
38 | }
39 | return os.toByteArray();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_pack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/drawable-xhdpi/ic_pack.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_unfolded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/drawable-xhdpi/ic_unfolded.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner6_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_gray.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/select_pdf_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/select_viewer_state.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/stroke_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
28 |
29 |
41 |
42 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_viewpage_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/listitem_guide.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
21 |
22 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #f2f4f5
7 |
8 | #666666
9 | #1f89ed
10 |
11 |
12 | #DBDBDB
13 |
14 | #333333
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PDFiumPdfViewer
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/cn/xiaolong/pdfiumpdfviewer/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cn.xiaolong.pdfiumpdfviewer;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 | classpath 'me.tatarka:gradle-retrolambda:3.3.1'
10 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
11 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Aug 08 17:23:14 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/lucky.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiaolongonly/PDFiumForAndroidDemo/a73ad07515b566d7f3a0dbdf08c336b2eafcf2c1/lucky.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------