如何在Android的TextView中在文本下方添加红色波浪线

时间:2014-12-03 08:51:21

标签: android spannablestring

我正在尝试在文本中的错误下添加红色波浪线,例如:

enter image description here

不幸的是我找不到合适的* Span类来包装错误文本。

我应该如何在Android中实现这样的功能?

3 个答案:

答案 0 :(得分:4)

我通过实现自定义Span解决了这个问题:

error_underline.png添加到您的资源:red wavy line< - 此处微小的6x3像素

然后使用此类创建跨度:

static class ErrorSpan extends DynamicDrawableSpan {

    private BitmapDrawable mRedWavy;
    private int mWidth;
    private int mBmpHeight;

    ErrorSpan(Resources resources) {
        super(DynamicDrawableSpan.ALIGN_BASELINE);
        mRedWavy = new BitmapDrawable(resources, BitmapFactory.decodeResource(resources, R.drawable.error_underline));
        mBmpHeight = mRedWavy.getIntrinsicHeight();
        mRedWavy.setTileModeX(TileMode.REPEAT);
    }

    @Override
    public Drawable getDrawable() {
        return mRedWavy;
    }

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


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

        mRedWavy.setBounds(0, 0, mWidth, mBmpHeight);
        canvas.save();
        canvas.translate(x, bottom-mBmpHeight);
        mRedWavy.draw(canvas);
        canvas.restore();
        canvas.drawText(text.subSequence(start, end).toString(), x, y, paint);
    }
}

答案 1 :(得分:3)

这是另一种不涉及资源的解决方案:

public class WavyUnderlineSpan implements LineBackgroundSpan {

private int color;
private int lineWidth;
private int waveSize;

public WavyUnderlineSpan() {
    this(Color.RED, 1, 3);
}

public WavyUnderlineSpan(int color, int lineWidth, int waveSize) {
    this.color = color;
    this.lineWidth = lineWidth;
    this.waveSize = waveSize;
}

@Override
public void drawBackground(Canvas canvas, Paint paint, int left, int right, int top, int baseline, int bottom,
                           CharSequence text, int start, int end, int lnum) {
    Paint p = new Paint(paint);
    p.setColor(color);
    p.setStrokeWidth(lineWidth);

    int width = (int) paint.measureText(text, start, end);
    int doubleWaveSize = waveSize * 2;
    for (int i = left; i < left + width; i += doubleWaveSize) {
        canvas.drawLine(i, bottom, i + waveSize, bottom - waveSize, p);
        canvas.drawLine(i + waveSize, bottom - waveSize, i + doubleWaveSize, bottom, p);
    }
}

}

答案 2 :(得分:1)

@ bpronin的代码对我不起作用 - 在高分辨率屏幕上跨度太小而且它跨越了整个文本,而不仅仅是错误跨越。

但是根据他的想法,我更新了我的答案,无需添加资源:

public void onClickButton(View v) {

    // Login Button
    if (v.getId() == R.id.Blogin) {
        EditText a = (EditText) findViewById(R.id.TFusername);
        String str = a.getText().toString();
        EditText b = (EditText) findViewById(R.id.TFpassword);
        String pass = b.getText().toString();

        String password = helper.searchPass(str);
        if (pass.equals(password)) {
        register_button.setEnabled(False)
            Intent i = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(i);
        } else {
        register_button.setEnabled(True)
            // Show Toast Message
            Toast temp = Toast.makeText(LoginActivity.this, "Username/ Password is incorrect!", Toast.LENGTH_SHORT);
            temp.show();
        }


    }

    // Create account Button
    if (v.getId() == R.id.Bsignup) {
        Intent i = new Intent(LoginActivity.this, SignUpActivity.class);
        startActivity(i);
    }

}