我有一个应用程序,可以分页大文本,并为每个单词或句子设置多个跨度.我正在使用ReplacementSpan为每个单词绘制背景.我不能使用BackgroundSpan,因为它太简单了,不能让我控制画布.由于ReplacementSpan扩展了MetricAffectingSpan,它影响了文本的布局,完全打破了我的分页.我正在使用StaticLayout来计算每个页面的文本,而StaticLayout不允许跨越,因此它可以计算跨越大小影响的先验.
ReplacementSpan有替代品吗?如何在不影响文本大小和布局的情况下绘制我想要的背景?
这是我的replacementspan的代码:
public class BackgroundcolorWithoutlineHeightSpan extends ReplacementSpan { private static final float DP_ACTIVE = VIEwsUtils.dptopx(4); private static final int DP_OUTSIDE_padding = (int) VIEwsUtils.dptopx(6); private static final float DP_PHRASE = VIEwsUtils.dptopx(4); private static final float DP_ROUNDED = VIEwsUtils.dptopx(3); private final int mcolor; private final int mTextHeight; private int mbordercolor; private boolean mIsSelected; private boolean mIsPhrase; public BackgroundcolorWithoutlineHeightSpan(int color,int textHeight,boolean isPhrase) { mcolor = color; mTextHeight = textHeight; mIsPhrase = isPhrase; } public BackgroundcolorWithoutlineHeightSpan(int color,boolean isSelected,int bordercolor,boolean isPhrase) { mcolor = color; mTextHeight = textHeight; mIsSelected = isSelected; mbordercolor = bordercolor; mIsPhrase = isPhrase; } @OverrIDe public int getSize(@NonNull Paint paint,CharSequence text,int start,int end,Paint.FontMetricsInt fm) { return Math.round(measureText(paint,text,start,end)); } @OverrIDe public voID draw(@NonNull Canvas canvas,float x,int top,int y,int bottom,Paint paint) { canvas.save(); Rect newRect = canvas.getClipBounds(); newRect.inset(-DP_OUTSIDE_padding,-DP_OUTSIDE_padding); canvas.clipRect(newRect,Region.Op.REPLACE); float measuredText = measureText(paint,end); int paintcolor = paint.getcolor(); if (!mIsSelected) { RectF rect; rect = new RectF(x,top,x + measuredText,top + mTextHeight); paint.setstrokeWIDth(0.0f); paint.setcolor(mcolor); paint.setStyle(Paint.Style.FILL); canvas.drawRoundRect(rect,DP_ROUNDED,paint); } else { RectF rect; if (mIsPhrase) { rect = new RectF(x - DP_PHRASE,top - DP_PHRASE,x + measuredText + DP_PHRASE,top + mTextHeight + DP_PHRASE); } else { rect = new RectF(x - DP_ACTIVE,top - DP_ACTIVE,x + measuredText + DP_ACTIVE,top + mTextHeight + DP_ACTIVE); } paint.setstrokeWIDth(0.0f); paint.setcolor(mcolor); paint.setStyle(Paint.Style.FILL); canvas.drawRoundRect(rect,paint); RectF border; if (mIsPhrase) { border = new RectF(x - DP_PHRASE,top + mTextHeight + DP_PHRASE); } else { border = new RectF(x - DP_ACTIVE,top + mTextHeight + DP_ACTIVE); } paint.setcolor(mbordercolor); paint.setstrokeWIDth(4.0f); paint.setStyle(Paint.Style.stroke); canvas.drawRoundRect(border,paint); } paint.setStyle(Paint.Style.FILL); paint.setcolor(paintcolor); canvas.drawText(text,end,x,y,paint); canvas.restore(); } private float measureText(Paint paint,int end) { return paint.measureText(text,end); }}
最佳答案尝试这个简单的跨度,它在所有跨度上绘制纯红色背景(即使它是多行跨度)但你可以绘制任何你喜欢的:class LBS implements lineBackgroundSpan { private final TextVIEw tv; private int start; private int end; public LBS(TextVIEw tv,int end) { this.tv = tv; this.start = start; this.end = end; } @OverrIDe public voID drawBackground(Canvas c,Paint p,int left,int right,int baseline,int lnum) { Layout layout = tv.getLayout(); int startline = layout.getlineForOffset(this.start); int endline = layout.getlineForOffset(this.end); if (startline <= lnum && lnum <= endline) { if (startline == lnum) { left = (int) layout.getPrimaryHorizontal(this.start); } if (endline == lnum) { right = (int) layout.getPrimaryHorizontal(this.end); } int origcolor = p.getcolor(); p.setcolor(color.RED); c.drawRect(left,right,bottom,p); p.setcolor(origcolor); } }}
测试代码(设置0和ssb.length()作为开始和结束不是非常有效,所以你可以优化它):
TextVIEw tv = new TextVIEw(this);setContentVIEw(tv);tv.setTextSize(32);SpannableStringBuilder ssb = new SpannableStringBuilder("Chop a handfull spinach,pork shoulder,and dill in a large cooker over medium heat,cook for six minutes and varnish with some bok choy.");LBS span = new LBS(tv,30,100);ssb.setSpan(span,ssb.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);tv.setText(ssb);Log.d(TAG,"onCreate text [" + ssb.subSequence(30,100) + "]");
编辑
如果您有多个单词来标记/突出显示,您可以使用它的修改版本:
class LBS implements lineBackgroundSpan { TextVIEw tv; List
测试代码:
TextVIEw tv = new TextVIEw(this); setContentVIEw(tv); tv.setTextSize(32); String text = "Chop a handfull spinach,cook for six minutes and varnish with some bok choy."; SpannableStringBuilder ssb = new SpannableStringBuilder(text); LBS span = new LBS(tv); String[] words = { "spinach,pork shoulder","cooker","with some bok choy",}; for (String word : words) { int IDx = text.indexOf(word); span.add(IDx,IDx + word.length()); } ssb.setSpan(span,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tv.setText(ssb);
总结 以上是内存溢出为你收集整理的Android中的ReplacementSpan替代方案全部内容,希望文章能够帮你解决Android中的ReplacementSpan替代方案所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)