摘要:在平板上做一个表格的样板展示。在文件过多的时候下面有一个类似CSDN博客的导航条。其中样板展示使用的pdf格式。里面涉及获取pdf首页截图,和pdf一个展示
简单的效果如上图:
RecyclerView滚动条
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_fold"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="false"
android:paddingTop="20px"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarSize="12px"
android:scrollbarStyle="outsideInset"
android:scrollbarThumbVertical="@drawable/fold_vertical_thumb"
android:scrollbarTrackVertical="@drawable/fold_vertical_track"
android:scrollbars="vertical"
android:verticalScrollbarPosition="right" />
属性 | 含义 |
---|---|
android:fadeScrollbars | 此项配置用来表示是否在不滚动时隐藏滚动条,可以选择true或false,默认为true,也就是不滚动时隐藏。如果将其设置为false,那么只要能够滚动,滚动条就会一直显示,不会隐藏。但如果不足一页,不能滚动,则不会显示。 |
android:scrollbarAlwaysDrawVerticalTrack | 此项配置表示是否总是显示垂直滚动条的Track,可以选择true或false,默认为false。通常,如果设置了滚动条的Track,那么Track会随着滚动条一起显示和隐藏。但如果设置了android:scrollbarAlwaysDrawVerticalTrack为true,则滚动条的Track将一直显示,不会隐藏。当然,如果没有配置android:scrollbarTrackVertical,即使设置了android:scrollbarAlwaysDrawVerticalTrack为true,也不会有Track显示。此外,android:fadeScrollbars配置为false,则无论android:scrollbarAlwaysDrawVerticalTrack配置为true还是false,Track都不会隐藏。 |
android:scrollbarSize | 此选项表示滚动条的大小 |
android:scrollbarStyle | 此项配置也是用来设置滚动条的位置,不过不是左右位置,而是滚动条和ListView内容之间的相对位置,它的取值范围是insideoverlay,insideInset,outsideoverlay,outsideinset。 |
android:scrollbarThumbVertical | (滑道)此选项用来控制垂直滚动条的显示外观,这也是美化滚动条时最重要的一项配置。它可以设置为一个颜色值,或者是一个Drawable资源。对Drawable资源可以使用.9的png图片,也可以使用XML来配置。 |
android:scrollbarTrackVertical | (滑块)此选项用来控制垂直滚动条背后滑动轨道的显示效果。和android:scrollbarThumbVertical配置一样,android:scrollbarTrackVertical可以设置为一个颜色值,或者是一个Drawable资源。 |
android:scrollbars | 此选项表示是否显示滚动条,它的取值可以是vertical,horizontal或none。 对ListView来说,它只能垂直滚动,将scrollbars设置成horizontal或者none效果都是一样的,也就是不会出现滚动条。所以如果不希望ListView显示滚动条,就将scrollbars设置成none。此外,如果scrollbars设置成none,那么其他的滚动条相关的配置都不会有效果。 |
android:verticalScrollbarPosition | 此项配置用来设置滚动条的位置 |
详细一点和点击效果设置可以查看之前这一篇文章 记录:在使用 Adapter是对 item的点击设置,合并,不同布局实现。其中android:scrollbarStyle有四中选着,其含义如下:
属性 | 含义 |
---|---|
insideoverlay | (默认值)表示滚动条右侧和ListView可用区域右侧对其,且覆盖在Item之上。 |
insideInset | 表示滚动条右侧和ListView可用区域右侧对其,但不覆盖在Item之上,而是将Item挤到滚动条的左边。 |
outsideoverlay | 表示滚动条右侧和ListView右侧对其,且覆盖在右侧padding之上。 |
outsideinset | 表示滚动条右侧和ListView可用区域右侧对其,但不覆盖在padding之上,而是将padding挤到滚动条的左边。 |
获取pdf的缩略图和加载
借助 PdfiumAndroid 获取pdf缩略图
/**
* 加载 pdf 的首页
*
* @param path
* @return
*/
private void decodeSampledBitmapFromResource(Context context, String path, int reqWidth, int reqHeight) {
File file = new File(path);
int pageNum = 0;
try {
ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
PdfiumCore pdfiumCore = new PdfiumCore(context);
PdfDocument pdfDocument = pdfiumCore.newDocument(fd);
pdfiumCore.openPage(pdfDocument, pageNum);
Size size = pdfiumCore.getPageSize(pdfDocument, pageNum);
int width = size.getWidth();
int height = size.getHeight();
/*
LogUtils.i(TAG, "pdf bitmap size width = " + width + ",height = " + height);
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
pdfiumCore.renderPageBitmap(pdfDocument, bitmap, pageNum, 0, 0,
width, height);
bitmap = scaleBitmap(bitmap, reqWidth, reqHeight);
*/
Bitmap bitmap = Bitmap.createBitmap(reqWidth, reqHeight,
Bitmap.Config.RGB_565);
pdfiumCore.renderPageBitmap(pdfDocument, bitmap, pageNum, 0, 0,
reqWidth, reqHeight);
//添加到缓存
addBitmapToLruCache(path, bitmap);
pdfiumCore.closeDocument(pdfDocument); // important!
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
在加载时候,遇到读取的尺寸为pdf的大小,其尺寸很大。从word转pdf都是一千多。通过AndroidPdfViewer 加载pdf。
mPdfView.fromFile(file)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this, true))
.spacing(0)
.onPageError(this)
.pageFitPolicy(FitPolicy.WIDTH)
.load();
下边页码导航和上边RecyclerView联动
主要利用 pager-layoutmanager 去满足分页功能。
- 计算总页数
- 通过position取出集合的文本数字
- 页数少于不带(…)最大显示页
- 点击的小标是集合第一个
- 点击的小标是集合最后一个
- 计算点击position左边,分为有(…)和无(…)
- 计算点击position左边,分为有(…)和无(…)
- 滑动和点击双重更新会导致集合数据清空重写,导致显示错乱。要在重新计算
通过点击position计算导航条内容集合
/**
* 通过点击下标,获取上一次文本值。通过文本值,重新计算新的集合,值的position
*
* @param position 点击 item的下标,从 0 开始
*/
private void calcPageList(int position) {
LogUtils.i(TAG, "index position = " + position);
//借鉴 CSDN 的博客下面的页码器. 默认选中项左右最多2个项(不包含自己),第一页和最后一个必须显示.如果第一项,和最后一下连接不上则用 ...替代
int total = mFileInfos.size();
int row = ROW;
int columns = COLUMNS;
//page 的数字记录 (下标 +1)
int about = 2; //左右显示带 ...
int only = 4; // 没有带 ...的显示
int pre; //点中项前一个数字
int next; //点中项后一个数字
int product = row * columns;
int number = total / product; //总共有多少页
if (total % product != 0) { //总页数
number = number + 1;
}
LogUtils.i(TAG, "number = " + number + ",size = " + mPageInfos.size());
LogUtils.i(TAG, "index mPageInfos = " + Arrays.toString(mPageInfos.toArray()));
//根据下标获取上面的页码,默认第一页
String page = "1";
int num = 0;
if (!mPageInfos.isEmpty() && position < mPageInfos.size()) {
String str = mPageInfos.get(position);
if (!ellipsis.equals(str) && !TextUtils.isEmpty(str)) {
page = str;
num = Integer.valueOf(str);
}
}
LogUtils.i(TAG, "page = " + page + ",num = " + num);
mPageInfos.clear();
if (number <= only) {
for (int i = 0; i < number; i++) {
mPageInfos.add(String.valueOf(i + 1));
}
//需要上一次点击文本数字,现在新集合的下标
mPageAdapter.setSelected(getPageIndex(page));
mPageAdapter.notifyDataSetChanged();
return;
}
//这里要开始判断 position,简介判读是否需要 ...
if (position == 0) { //如果选中的是第一个
for (int i = 0; i <= about; i++) {
mPageInfos.add(String.valueOf(i + 1));
}
mPageInfos.add(ellipsis);
mPageInfos.add(String.valueOf(number));
mPageAdapter.setSelected(getPageIndex(page));
mPageAdapter.notifyDataSetChanged();
return;
}
if (position == (number - 1)) { //如果选中的是最后一个
mPageInfos.add("1");
mPageInfos.add(ellipsis);
for (int i = about; i >= 0; i--) {
mPageInfos.add(String.valueOf(number - i));
}
mPageAdapter.setSelected(getPageIndex(page));
mPageAdapter.notifyDataSetChanged();
return;
}
//既不是第一,也不是最后一个。需要计算左右值
pre = num - about;
if (pre <= 1) { //点击的不够远,不足添加 ...(这里设置成1,因为是不包含本身有2个)
//从当的点击位置,开始添加前面的数
for (int i = 1; i < num; i++) {
mPageInfos.add(String.valueOf(i));
}
} else { //需要 ...
mPageInfos.add("1");
mPageInfos.add(ellipsis);
for (int i = about; i > 0; i--) {
mPageInfos.add(String.valueOf(num - i));
}
}
//添加点项
mPageInfos.add(String.valueOf(num));
next = num + about;
if (next >= number) { //不够远,不需要 ...
for (int i = num; i < number; i++) {
mPageInfos.add(String.valueOf(i + 1));
}
} else { //需要...
for (int i = 0; i < about; i++) {
mPageInfos.add(String.valueOf(num + (i + 1)));
}
mPageInfos.add(ellipsis);
mPageInfos.add(String.valueOf(number));
}
mPageAdapter.setSelected(getPageIndex(page));
mPageAdapter.notifyDataSetChanged();
}
滑动和点击两次更新,导致数据集合删除,重计算问题
mPagerGridLayoutManager.scrollToPage((page - 1)); //文本数字比下标+1
//注意: 上面的方法会回调onPageSelect(int) 方法,导致 calcPageList(int)重新计算了 mPagesInfo集合,需要重新之前点击的文本,在新集合里面的位置
calcPageList(getPageIndex(str));