Frage

I have a TextView which has a SpannableString inside it to highlight searched terms. Like so :

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"/>

As can be seen I am using android:lineSpacingExtra to give the lines a nice spacing, however it is causing the SpannableString background to be too tall. I would like to keep the spacing between the lines but make the SpannableString shorter.

How is this possible?

War es hilfreich?

Lösung

You can create your own span by extending ReplacementSpan. In draw method, you can take into account the fontSpacing which you can get from Paint parameter.

Like this:

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);
    }

}

You can use it like this:

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);

I couldn't much test it but you can improve it.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top