Android一个页码的导航条

摘要:在平板上做一个表格的样板展示。在文件过多的时候下面有一个类似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 去满足分页功能。

  1. 计算总页数
  2. 通过position取出集合的文本数字
  3. 页数少于不带(…)最大显示页
  4. 点击的小标是集合第一个
  5. 点击的小标是集合最后一个
  6. 计算点击position左边,分为有(…)和无(…)
  7. 计算点击position左边,分为有(…)和无(…)
  8. 滑动和点击双重更新会导致集合数据清空重写,导致显示错乱。要在重新计算

通过点击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代码下载

发布了32 篇原创文章 · 获赞 6 · 访问量 6万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览