Use a SpannableString and apply a ReplacementSpan:
public class ZigZagUnderlineSpan extends ReplacementSpan{
private Paint linePaint;
private int textMessureWidth;
private float lineOffsetFromTextBottom = 0;
private float lineSpaceX = 6;
private float lineSpaceY = 6;
public ZigZagUnderlineSpan(){
linePaint = new Paint();
linePaint.setColor(Color.RED);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(2);
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
textMessureWidth = (int)paint.measureText(text, start, end);
Paint.FontMetricsInt metrics = paint.getFontMetricsInt();
if (fm != null) {
fm.ascent = metrics.ascent;
fm.descent = metrics.descent;
fm.top = metrics.top;
fm.bottom = metrics.bottom;
}
return textMessureWidth;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
canvas.drawText(text, start, end, x, y, paint);
float lineY = y + lineOffsetFromTextBottom;
float xLeft = paint.measureText(text, 0, start);
Path path = new Path();
path.moveTo(xLeft, lineY);
float vertexX = xLeft;
float vertexY = lineY;
for(int n = 0; n < textMessureWidth / lineSpaceX; n++){
path.lineTo(vertexX, vertexY);
vertexX += lineSpaceX;
if (n % 2 == 0) {
vertexY = lineY + lineSpaceY;
}else{
vertexY = lineY;
}
}
path.lineTo(textMessureWidth, vertexY);
canvas.drawPath(path, linePaint);
}
}
Use this:
SpannableString spannableString = new SpannableString("Texto errado");
spannableString.setSpan(new ZigZagUnderlineSpan(),0,spannableString.length(),SpannableString.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannableString);