Separate long text on viewing pages

I am implementing the messureText method in this question to split long text into pages with specified size before rendering in the viewpager. I'm doing a while loop with an extra number of characters to get the text blocks I want, but it doesn't seem to be the best solution. Is there any suggestion to improve performance for this calculation? p / s: I am accessing the Wattpad app after seeing that it does it very quickly, but did not know how to do it?

+3


source to share


2 answers


StaticLayout or DynamicLayout could do it. Android apps (Boring | Static | Dynamic) to measure and wrap text, these class constructors take CharSequence as an input, so styles text (containing spaces, even ImageSpan) is acceptable. You can calculate pageWidth and pageHeight according to your view or screen, and the TextPaint parameter and two LineSpacing parameters should match your target TextView, here is my code:



import android.text.Layout;
import android.text.SpannableStringBuilder;
import android.text.StaticLayout;
import android.text.TextPaint;

import java.util.ArrayList;
import java.util.List;

public class PageSplitter {
    private final int pageWidth;
    private final int pageHeight;
    private final float lineSpacingMultiplier;
    private final float lineSpacingExtra;
    private final List<CharSequence> pages = new ArrayList<CharSequence>();
    private SpannableStringBuilder mSpannableStringBuilder = new SpannableStringBuilder();

    public PageSplitter(int pageWidth, int pageHeight, float lineSpacingMultiplier, float lineSpacingExtra) {
        this.pageWidth = pageWidth;
        this.pageHeight = pageHeight;
        this.lineSpacingMultiplier = lineSpacingMultiplier;
        this.lineSpacingExtra = lineSpacingExtra;
    }

    public void append(CharSequence charSequence) {
        mSpannableStringBuilder.append(charSequence);
    }

    public void split(TextPaint textPaint) {
        StaticLayout staticLayout = new StaticLayout(
                mSpannableStringBuilder,
                textPaint,
                pageWidth,
                Layout.Alignment.ALIGN_NORMAL,
                lineSpacingMultiplier,
                lineSpacingExtra,
                false
        );
        int startLine = 0;
        while(startLine < staticLayout.getLineCount()) {
            int startLineTop = staticLayout.getLineTop(startLine);
            int endLine = staticLayout.getLineForVertical(startLineTop + pageHeight);
            int endLineBottom = staticLayout.getLineBottom(endLine);
            int lastFullyVisibleLine;
            if(endLineBottom > startLineTop + pageHeight)
                lastFullyVisibleLine = endLine - 1;
            else
                lastFullyVisibleLine = endLine;
            int startOffset = staticLayout.getLineStart(startLine);
            int endOffset = staticLayout.getLineEnd(lastFullyVisibleLine);
            pages.add(mSpannableStringBuilder.subSequence(startOffset, endOffset));
            startLine = lastFullyVisibleLine + 1;
        }
    }

    public List<CharSequence> getPages() {
        return pages;
    }
}

      

+5


source


You can use BufferedReader

in your code. You can just leave the line there and go to work in this reader. It would be more efficient than creating a String from it first.



0


source







All Articles