Android 如何在安卓系统中使用另一种颜色的桌面?

Android 如何在安卓系统中使用另一种颜色的桌面?,android,user-interface,html,spannable,Android,User Interface,Html,Spannable,我想让Spanable看起来像IDEs中的错误-用另一种颜色加下划线 我试图创建扩展androidUnderlineSpan的ColorUnderlineSpan类,但它使所有文本都变成另一种颜色(我只需要添加彩色下划线): 我还找到了DynamicDrawableSpan类,但我看不到要绘制的画布边界 如果能用带边界参数的抽象绘制方法获得任何可扩展的impl,那就太好了。这不是最漂亮的解决方案,但它最终对我有效: public class CustomUnderlineSpan impleme

我想让Spanable看起来像IDEs中的错误-用另一种颜色加下划线

我试图创建扩展android
UnderlineSpan
ColorUnderlineSpan
类,但它使所有文本都变成另一种颜色(我只需要添加彩色下划线):

我还找到了
DynamicDrawableSpan
类,但我看不到要绘制的画布边界


如果能用带边界参数的抽象绘制方法获得任何可扩展的impl,那就太好了。

这不是最漂亮的解决方案,但它最终对我有效:

public class CustomUnderlineSpan implements LineBackgroundSpan {

int color;
Paint p;
int start, end;
public CustomUnderlineSpan(int underlineColor, int underlineStart, int underlineEnd) {
    super();
    color = underlineColor;
    this.start = underlineStart;
    this.end = underlineEnd;
    p = new Paint();
    p.setColor(color);
    p.setStrokeWidth(3F);
    p.setStyle(Paint.Style.FILL_AND_STROKE);
}

@Override
public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {

    if (this.end < start) return;
    if (this.start > end) return;

    int offsetX = 0;
    if (this.start > start) {
        offsetX = (int)p.measureText(text.subSequence(start, this.start).toString());
    }

    int length = (int)p.measureText(text.subSequence(Math.max(start, this.start), Math.min(end, this.end)).toString());
    c.drawLine(offsetX, baseline + 3F, length + offsetX, baseline + 3F, this.p);
}
公共类CustomUnderlineSpan实现LineBackgroundSpan{
内色;
油漆p;
int开始,结束;
公共自定义下划线窗格(int-underlineColor、int-underlineStart、int-underlineEnd){
超级();
颜色=下划线颜色;
this.start=underlineStart;
this.end=underlined;
p=新油漆();
p、 设置颜色(颜色);
p、 设定行程宽度(3F);
p、 设置样式(绘制、样式、填充和笔划);
}
@凌驾
公共无效牵引地面(画布c、绘制p、int left、int right、int top、int baseline、int bottom、CharSequence text、int start、int end、int lnum){
如果(this.endend)返回;
int offsetX=0;
如果(this.start>start){
offsetX=(int)p.measureText(text.subSequence(start,this.start.toString());
}
int length=(int)p.measureText(text.subSequence(Math.max(start,this.start),Math.min(end,this.end)).toString();
c、 抽绳(偏移量,基线+3F,长度+偏移量,基线+3F,this.p);
}

这很奇怪,因为你必须指定字符索引来开始和结束下划线,但这对我很有效。

答案@korbonix posted很好。我在Kotlin和支持多行文本视图方面做了一些改进:

class ColorUnderlineSpan(val underlineColor: Int, val underlineStart: Int, val underlineEnd: Int): LineBackgroundSpan {

    val paint = Paint()

    init {
        paint.color = underlineColor
        paint.strokeWidth = 3.0f
        paint.style = Paint.Style.FILL_AND_STROKE
    }

    override fun drawBackground(c: Canvas?, p: Paint?, left: Int, right: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence?, start: Int, end: Int, lnum: Int) {
        if (!(underlineStart < underlineEnd)) {
            throw Error("underlineEnd should be greater than underlineStart")
        }

        if (underlineStart > end || underlineEnd < start) {
            return
        }

        var offsetX = 0

        if (underlineStart > start) {
            offsetX = p?.measureText(text?.subSequence(start, underlineStart).toString())?.toInt() ?: 0
        }

        val length: Int = p?.measureText(text?.subSequence(Math.max(start, underlineStart), Math.min(end, underlineEnd)).toString())?.toInt()
            ?: 0

        c?.drawLine(offsetX.toFloat(), baseline + 3.0f, (length + offsetX).toFloat(), baseline + 3.0f, paint)
    }
}

感谢分享您的解决方案,我将为其提供一个tryExcellent解决方案。缓存offsetX和每帧调用DruckGround后的长度可以极大地提高性能。是否有任何演示代码来检查这一点?这很有吸引力。我在Kotlin发布了另一个基于此的答案,并支持多行文本视图。谢谢!这是一个很好的解决方案,但我注意到计算只适用于左对齐的文本。遗憾的是,当文本是右对齐/右对齐时,此解决方案不起作用。:(这不适用于多行。我想你应该使用lnum Int作为偏移
class ColorUnderlineSpan(val underlineColor: Int, val underlineStart: Int, val underlineEnd: Int): LineBackgroundSpan {

    val paint = Paint()

    init {
        paint.color = underlineColor
        paint.strokeWidth = 3.0f
        paint.style = Paint.Style.FILL_AND_STROKE
    }

    override fun drawBackground(c: Canvas?, p: Paint?, left: Int, right: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence?, start: Int, end: Int, lnum: Int) {
        if (!(underlineStart < underlineEnd)) {
            throw Error("underlineEnd should be greater than underlineStart")
        }

        if (underlineStart > end || underlineEnd < start) {
            return
        }

        var offsetX = 0

        if (underlineStart > start) {
            offsetX = p?.measureText(text?.subSequence(start, underlineStart).toString())?.toInt() ?: 0
        }

        val length: Int = p?.measureText(text?.subSequence(Math.max(start, underlineStart), Math.min(end, underlineEnd)).toString())?.toInt()
            ?: 0

        c?.drawLine(offsetX.toFloat(), baseline + 3.0f, (length + offsetX).toFloat(), baseline + 3.0f, paint)
    }
}
    // Sets link color
    val spannable = SpannableString(getString(R.string.forgot_text))
    spannable.setSpan(
            ColorUnderlineSpan(Color.RED), 112, 127),
            0, 127, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    textText.text = spannable