Android一个页码的导航条
16lz
2021-01-25
摘要:在平板上做一个表格的样板展示。在文件过多的时候下面有一个类似CSDN博客的导航条。其中样板展示使用的pdf格式。里面涉及获取pdf首页截图,和pdf一个展示
简单的效果如上图:
RecyclerView滚动条
.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));
相关下载
ExcelMode代码下载
更多相关文章
- 为什么要学习 Markdown?究竟有什么用?
- Android使用ViewDragHelper实现简单的view拖拽和吸边功能
- 图解Android(安卓)View的scrollTo(),scrollBy(),getScrollX(), g
- [android] 百度地图开发 (三).定位当前位置及getLastKnownLocati
- Android去除TextView文本中的默认内边距
- android中引用项目工程中的sqlite文件
- Toast用法
- Android中使用kotlin实现多行文本的上下滚动播放
- Android的PopupWindow的使用,根据点击位置显示弹窗