I'm implementing messureText method in this question to separate long text into pages with specified size before rendering in viewpager. I'm doing a while loop with incremental number of characters to get desired text blocks but it seems not to be the best solution. Is there any suggestion to improve the performance for this calculation?. p/s: I refer to the Wattpad app saw it do this very fast but did not know it how?
StaticLayout or DynamicLayout could do this.
Android use (Boring
|Static
|Dynamic
)Layout classes to measure and wrap text, these classes constructor take CharSequence
as input param so styled text(contains spans, even ImageSpan
) is acceptable.
You can calculate the pageWidth
and pageHeight
according to your View or Screen, and the TextPaint
and two lineSpacing
param must equals to 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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With