Android中的ReplacementSpan替代方案

Android中的ReplacementSpan替代方案,第1张

概述我有一个应用程序,可以分页大文本,并为每个单词或句子设置多个跨度.我正在使用ReplacementSpan为每个单词绘制背景.我不能使用BackgroundSpan,因为它太简单了,不能让我控制画布.由于ReplacementSpan扩展了MetricAffectingSpan,它影响了文本的布局,完全打破了我的分页.我正在使用StaticLayout来计算

我有一个应用程序,可以分页大文本,并为每个单词或句子设置多个跨度.我正在使用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替代方案所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1139411.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)