android - 如何限制 spannablestring 的行高但保持行的其余部分

标签 android formatting textview highlight spannablestring

我有一个 TextView,里面有一个 SpannableString 来突出显示搜索到的词。像这样:

enter image description here

<TextView android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:id="@+id/textBox"
          android:textSize="16sp"
          android:paddingTop="10dp"
          android:paddingLeft="20dp"
          android:paddingRight="20dp"
          android:lineSpacingExtra="5dp"
          android:textColor="@color/TextGray"/>

可以看出,我正在使用 android:lineSpacingExtra 为线条提供合适的间距,但它会导致 SpannableString 背景太高。我想保持行之间的间距,但使 SpannableString 更短。

这怎么可能?

最佳答案

您可以通过扩展 ReplacementSpan 创建自己的跨度.在draw 方法中,您可以考虑从Paint 参数中获取的fontSpacing

像这样:

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.RectF;
import android.text.style.ReplacementSpan;

public class BetterHighlightSpan extends ReplacementSpan {

    private int backgroundColor;
    public BetterHighlightSpan(int backgroundColor) {
        super();
        this.backgroundColor = backgroundColor;
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
        return Math.round(paint.measureText(text, start, end));
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
            Paint paint) {

        // save current color
        int oldColor = paint.getColor();

        // calculate new bottom position considering the fontSpacing
        float fontSpacing = paint.getFontSpacing();
        float newBottom = bottom - fontSpacing;

        // change color and draw background highlight
        RectF rect = new RectF(x, top, x + paint.measureText(text, start, end), newBottom);
        paint.setColor(backgroundColor);
        canvas.drawRect(rect, paint);

        // revert color and draw text
        paint.setColor(oldColor);
        canvas.drawText(text, start, end, x, y, paint);
    }

}

你可以这样使用它:

TextView textView = (TextView) findViewById(R.id.textView);
SpannableStringBuilder builder = new SpannableStringBuilder("here some text and more of it");
builder.setSpan(new BetterHighlightSpan(Color.CYAN), 4, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(builder);

我无法对其进行太多测试,但您可以对其进行改进。

关于android - 如何限制 spannablestring 的行高但保持行的其余部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20435798/

相关文章:

Android 录音来电和去电

javascript - 通过自定义 Cordova 方案获得安全来源

android - fragment 的 setEnterTransition() 和 setExitTransition() 方法如何工作?

git - 在推送时让 git 重新格式化源代码

c# - 在 C# 中格式化日期时间

java - 对于 SQLite (Eclipse),将数据库从本地导入到模拟器,反之亦然

java - 在 HTML 中格式化 java 代码以像在 IDE 中一样显示它

java - 如何动态设置形成 ListView 行的多个 TextView 中的文本大小?

java - TextView 中的文本数量有限

android - 无法解析 android.support.design。迁移到 AndroidX 后