如何对长文本进行分页?

5

我有一段长文本和一个固定大小的textView。如何分页显示文本?用户将以以下方式与程序交互:向左或向右滑动以切换到上一页或下一页。

目前,我创建了一个PageManager来处理这个任务。但是它的功能非常有限。处理文本的核心代码如下:

while (true) {
        newLineIndex = TextUtils.indexOf(content, '\n', processIndex);
        if (newLineIndex == -1) {// till the end of content
            charCount = paint.breakText(content, processIndex, content.length(), false, leftLines * lineWidth, width);
        } else {
            charCount = paint.breakText(content, processIndex, ++newLineIndex, false, leftLines * lineWidth, width);
        }

        leftLines = (int) ((leftLines * lineWidth - width[0]) / lineWidth);
        processIndex += charCount;

        if (leftLines < 1 || processIndex >= content.length()) {
            page = new Page();
            page.endIndex = processIndex;
            page.startIndex = pageBaseLine;
            page.content = content.subSequence(page.startIndex, page.endIndex);
            result.add(page);
            pageBaseLine = processIndex;

            leftLines = lineNumber;
        }

        if (processIndex >= content.length()) {
            break;
        }
    }

限制是页面可能会截断文本,例如:
|A lon|
|g wor|
|d man|

// 一个长单词的人

或者由于换行导致的不正确的行:

// 页面管理器计算这个(2 行):

|a sentence with loooooooo|

|ooong word abcdefghijklmn|

//但实际上在文本视图中(3行):

|a sentence with           |

|looooooooooong word      |

|abcdefghijklmn           |

所以最终的行数比计算的要多。所以我的页面管理器很愚蠢。有人能帮我吗?谢谢!

由于这是一个与算法相关的问题,也许您应该考虑在http://programmers.stackexchange.com/上发布它。 - Arnab Chakraborty
请看我的答案,链接在这里:https://dev59.com/7nnZa4cB1Zd3GeqPrY7u - mixel
1个回答

5
可能已经太晚回答了,但我会分享一下我是如何解决这个问题的。
我做了一个类似的项目,但是针对的是安卓平板电脑。在我的应用程序中,我有系统底部栏、导航栏和标题栏。这些 Activity 的部分不参与文本预览,所以我想在计算中将它们排除。对于 750 像素的屏幕,这些部分占据了屏幕的 24%,大约是 180 像素。因此,我使用以下算法来查看文本视图中的文本:
  1. 计算查看文本的实际高度,即我的 TextView 的高度:ScreenHeight - ScreenHeight*0.24
  2. 设置文本大小,例如 14.0
  3. 计算文本文件中的行数
  4. 计算每页的行数:实际高度/文本大小
  5. 计算页面数量并将其加载到 HashMap 中
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight() — 0.24*display.getHeight();
mLinesInPage = (int) (Math.floor(height / mTextSize));
mPages = (int) (Math.ceil(mLinesInText / mLinesInPage));

格式化和其他转换是“即时执行”的。这很简单,但对我很有用。以下是示例:

在使用算法之前:

enter image description here

在使用算法之后:

enter image description here

enter image description here


1
我也遇到了同样的问题,但是我不太明白你的代码是如何解决这个问题的...也许是因为我不理解你是如何计算'mLinesInText'的。能否请@Sigrlami再详细解释一下呢? - kort.es
@kort.es 你可以通过读取整个文本并计算换行符"\n"来获取mLinesInText。当然,如果以某种方式重新格式化文本,则应重新计算此参数。 - sigrlami
@henry-sou,这有帮助到你吗? - sigrlami
每个设备都必须用这种方式获取实际高度屏幕吗? ScreenHeight - ScreenHeight0.24(始终减去ScreenHeight0.24)? - dreamfighter
1
@dreamfighter 0.24是经验值,因为您的应用程序实际屏幕由于顶部的操作栏和底部的系统栏而变小。它可能会因不同设备而改变。 - sigrlami
@BaDo 这是一个实际的应用程序。我不能分享我的代码。请在 Stack Overflow 上提出另一个具体问题,我会尽力帮助你。 - sigrlami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接