Android 是否可以通过一次调用Canvas.drawText()来显示多色文本?

Android 是否可以通过一次调用Canvas.drawText()来显示多色文本?,android,android-canvas,Android,Android Canvas,我想使用Canvas.drawText()显示多色文本。更具体地说,我想突出显示传递给drawText()方法的文本的子字符串 文本的形式为带有0个或多个ForegroundColorSpan对象的SpannableString 查看Canvas代码,似乎对传递的CharSequence调用.toString()意味着这是不可能的 还有别的办法吗 编辑:文本可能会偶尔更改(全部更改,而不是增量更改)。此外,在自定义视图中,可能有多个文本位于不同的不相关位置。如果使用TextView,请尝试类似的

我想使用Canvas.drawText()显示多色文本。更具体地说,我想突出显示传递给drawText()方法的文本的子字符串

文本的形式为带有0个或多个ForegroundColorSpan对象的SpannableString

查看Canvas代码,似乎对传递的CharSequence调用.toString()意味着这是不可能的

还有别的办法吗


编辑:文本可能会偶尔更改(全部更改,而不是增量更改)。此外,在自定义视图中,可能有多个文本位于不同的不相关位置。

如果使用TextView,请尝试类似的操作

String multiColorText = "<font color=0xff0000>Multi</font><font color=0x000000>Color</font><font color=0xccffff>Text</font>";

textView.setText(Html.fromHtml(multiColorText));

是的,可以使用其中一个类。这些是用于将文本绘制到画布的帮助器类,它们支持可扩展性。如果文本没有更改,请使用静态布局

示例

将其添加到自定义视图类

private StaticLayout layout;
将此代码放入
onLayout
onSizeChanged

Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");  

wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

TextPaint paint = new TextPaint();
paint.setTextSize(20f);
paint.setColor(Color.RED);
layout = new StaticLayout(wordtoSpan, paint, getWidth(), Alignment.ALIGN_NORMAL, 1, 0, false);
然后在绘图方法中,只需调用

layout.draw(canvas);
如果您的文本经常更改,您可以使用
dynamicclayout

Editable.Factory fac = Editable.Factory.getInstance();
Editable edit = fac.newEditable(wordtoSpan);
DynamicLayout layout = new DynamicLayout(edit,paint,getWidth(),Alignment.ALIGN_CENTER,1,0,false);
使用编辑对象更改文本

edit.append("hello");

无论何时为该视图编写文本,都可以设置thatView.setBackgroundResource(R.drawable.multicolor)

multicolor.xml中写入

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="rectangle"> 
    <gradient 
            android:startColor="@color/tabBgStart"
            android:endColor="@color/tabBgEnd"
            android:angle="270"/> 
</shape> 

希望它一定能奏效


要更改文本颜色,可以使用yourView.setTextColor(R.drawable.multicolor)我没有在画布中使用。请参阅下面的代码,了解我如何在textview中使用它

public TextView getTextClipArt1(){
    TextView textView = new TextView(context);
    Typeface tf = new MyTypeface(context, 0).getTypeface();

    Shader textShader=new LinearGradient(0, 0, 0, 30,
            new int[]{Color.GREEN,Color.BLUE},
            new float[]{0, 1}, TileMode.CLAMP);

    textView.setTypeface(tf);
    textView.getPaint().setShader(textShader);
    textView.getPaint().setStyle(Paint.Style.STROKE);
    textView.getPaint().setStrokeWidth(2);
    textView.setText("ABC");
    textView.setTextSize(30);
    textView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    return textView;
}
现在可以在画布上以位图的形式绘制textview,尽管我认为这些方法也存在于paint类中。
希望对您有用。

将着色器用于多色文本谢谢,但我不知道如何实现这一点。特别是哪个着色器类?抱歉,我没有使用TextView。非常好,谢谢。这看起来很有希望。在我的例子中,文本确实发生了变化。在这种情况下,是否可以使用某种invalidate()调用来实现我想要的功能?在这种情况下,每次文本更改时,您只需使用或创建一个新布局。好的,我将对此进行研究。事实上,我正在显示多个字符串,所以我假设每个字符串都显示一个字符串?此外,当文本更改时,整个文本也会更改(即,它与在EditText中编辑的文本不同)。这会影响所需的解决方案吗?您可以将所有这些字符串组合成一个字符串“TextUtils.concat(span1,span2);”它们在整个自定义视图中以看似随机的位置写入。准确的定位至关重要。
public TextView getTextClipArt1(){
    TextView textView = new TextView(context);
    Typeface tf = new MyTypeface(context, 0).getTypeface();

    Shader textShader=new LinearGradient(0, 0, 0, 30,
            new int[]{Color.GREEN,Color.BLUE},
            new float[]{0, 1}, TileMode.CLAMP);

    textView.setTypeface(tf);
    textView.getPaint().setShader(textShader);
    textView.getPaint().setStyle(Paint.Style.STROKE);
    textView.getPaint().setStrokeWidth(2);
    textView.setText("ABC");
    textView.setTextSize(30);
    textView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    return textView;
}