Is it possible to display multi-color text with on

2019-01-23 07:59发布

问题:

I would like to use Canvas.drawText() to display multi-color text. More specifically, I want to highlight a substring of the text passed to the drawText() method.

The text is in the form of a SpannableString with 0 or more ForegroundColorSpan objects.

Looking at the Canvas code, it appears that a .toString() call on the passed CharSequence, means that this is not possible.

Is there an alternative way?

EDIT: The text may occasionally change (total changes, not incremental). Also, there are potentially multiple texts positioned in different unrelated locations in the custom view.

回答1:

Yes it is possible by using one of the Layout classes. These are helper classes for drawing text to a canvas and they support Spannables. If your text doesn't change use a StaticLayout.

Example

Add this to your custom view class

private StaticLayout layout;

put this code into your onLayout or 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);

Then in your drawing method simply call

layout.draw(canvas);

In case your text changes often you can use a 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);

change text by using the edit object

edit.append("hello");


回答2:

i hvn't used in with Canvas. see below code how i used it in 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;
}

you can now draw textview as bitmap on canvas, Although i think these methods are also exist in paint class. Hope useful to you.



回答3:

Try something like this, if you use TextView

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

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

Edit : For SpannableString, check if the below helps you

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

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


回答4:

Whenever you write that text for that view you can set thatView.setBackgroundResource(R.drawable.multicolor); and

In multicolor.xml write

<?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> 

Hope it will works definitely

To Change the text color you can use yourView.setTextColor(R.drawable.multicolor);