【问题标题】:Is it possible to display multi-color text with one call to Canvas.drawText()?是否可以通过一次调用 Canvas.drawText() 来显示多色文本?
【发布时间】:2012-05-02 08:53:07
【问题描述】:

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

文本采用 SpannableString 形式,包含 0 个或多个 ForegroundColorSpan 对象。

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

还有其他方法吗?

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

【问题讨论】:

  • 对多色文本使用着色器
  • 谢谢,但我看不到如何实现这一点。特别是哪个着色器类?

标签: android android-canvas


【解决方案1】:

是的,可以使用Layout 类之一。这些是用于在画布上绘制文本的辅助类,它们支持 Spannables。如果您的文本没有更改,请使用 StaticLayout。

示例

将此添加到您的自定义视图类

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

如果您的文本经常更改,您可以使用DynamicLayout。

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

【讨论】:

  • 太好了,谢谢。这看起来很有希望。就我而言,文本确实发生了变化。在这种情况下,是否可以使用某种 invalidate() 调用来实现我想要的?
  • 在这种情况下,您只需使用DynamicLayout 或在每次文本更改时创建一个新布局。
  • 好的,我会调查的。事实上,我正在显示多个字符串,所以我想每个字符串都有一个 DynamicLayout?此外,当文本更改时,整个文本都会更改(即,它不像在 EditText 中编辑的文本)。这会影响所需的解决方案吗?
  • 您可以将所有这些字符串组合成一个字符串 'TextUtils.concat(span1, span2);'
  • 它们被写在整个自定义视图中看似随机的位置。准确定位至关重要。
【解决方案2】:

如果你使用 TextView,试试这样的方法

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

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

编辑: 对于 SpannableString,请检查以下内容是否对您有帮助

Spannable WordtoSpan = new SpannableString("partial colored text"); 

WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

【讨论】:

  • 抱歉,我没有使用 TextView。
【解决方案3】:

每当您为该视图编写文本时,您都可以设置 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);

【讨论】:

    【解决方案4】:

    我没有在 Canvas 中使用过。请参阅下面的代码我如何在 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;
    }
    

    您现在可以在画布上将文本视图绘制为位图,虽然我认为这些方法也存在于绘画类中。 希望对你有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多