20

I need to create an app for android, where the 2-color text will be displayed on the 2-color background. See picture on the left. Then, the line should be moved with animation and result image should be like on the picture on the right.

I have the following questions:

  1. Should I use some 2d engine to do this? Or, will it be OK to use standard views? How to do it?
  2. How to draw the text like on the pictures?

pic1 --------- pic2

LA_
  • 19,823
  • 58
  • 172
  • 308
  • I can tall you this, this is not easy task at all. But very good beginning could be to use some customized component such as canvas – Lukap Sep 12 '11 at 19:49
  • Is there any function, which can revert the text color depending on background? – LA_ Sep 13 '11 at 08:34
  • have you figured out how to implement this? i might have an answer if you didn't – Ludevik Nov 14 '11 at 10:44
  • @Ludevik, I have not. Will be waiting for your answer then ;) – LA_ Nov 14 '11 at 15:28
  • 4 years later you're opening a bounty? I can't think of a simpler way than the below answer for doing it in the Android graphics API. With a game engine like Libgdx, it would be easy. 1. Draw white text on black background to a frame buffer object. 2. Draw mask as white on black to another frame buffer object. 3. Draw the two frame buffer object's color textures to the screen with a shader that uses the mask to invert colors. – Tenfour04 Oct 20 '15 at 13:28
  • I think it should be easy with shaders. First, draw the complete text in white over black background. And then run invert the colors of the part you want with a mask... – danikaze Oct 23 '15 at 15:57

3 Answers3

17

In Android graphics API i would use clip path to create clip region. Steps:

  • fill canvas with black color:

black canvas

  • draw your white text on canvas:

enter image description here

enter image description here

  • draw the same text as in step 2 in black on canvas:

enter image description here

Marco Feregrino
  • 665
  • 5
  • 15
Ludevik
  • 6,954
  • 1
  • 41
  • 59
7

You can create a custom view that masks your text using a PorterDuff filter.

Here is how it could look:

public class MaskedText extends View {

    String sText;
    Paint p, pReplace, pMask;

    public MaskedText(Context context, AttributeSet attrs) {
        super(context, attrs);

        // base paint for you text
        p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setTextSize(40);
        p.setTextAlign(Paint.Align.CENTER);
        p.setColor(0xFF000000);
        p.setStyle(Paint.Style.FILL);

        // replacement color you want for your the part of the text that is masked
        pReplace = new Paint(p);
        pReplace.setColor(0xFFFFFFFF);
        pReplace.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));

        // color of the drawing you want to mask with text
        pMask = new Paint();
        pMask.setColor(0xFFFF0000);
        pMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    }

    public void setText(String text) {
        sText = text;
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();

        // here you draw the text with the base color. In your case black
        canvas.drawText(sText, getWidth() / 2, getHeight() / 2, p);

        // then draw the shape any graphics that you want on top of it
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 50, pMask);
        canvas.drawCircle(getWidth() / 2 + 50, getHeight()/2 + 5, 20, pMask);
        canvas.drawCircle(getWidth() / 2 - 45, getHeight()/2 - 10, 30, pMask);

        // finally redraw the text masking the graphics
        canvas.drawText(sText, getWidth()/2, getHeight()/2, pReplace);

        canvas.restore();
    }
}

This is the result: Masked text

Pol
  • 306
  • 2
  • 12
1

This is not complete answer I just giving suggestions. I know one possible solution how can you do the picture on the left and the picture on the right. But The part I cant figured out is the animation. I mean if you want smooth animation between states. If you just want to swap views that is easy, just take a view fliper and that it, but I do not think that you want to achieve that...

One of the things you can do is to set background let say with 320 width and let say 0-160 white and 160-320 black. Then

tv.setText(Html.fromHtml("<font color='black'>black on white</font> <font color='white'>white on black</font>"));

of course you will need to do precise calculation of how many letters will be black and how many white, but that is the concept

Lukap
  • 31,523
  • 64
  • 157
  • 244
  • I think there is more easy solution - I need to draw the text twice - first with white color and secondly with black. But I shouldn't use standard TextViews for this. – LA_ Sep 13 '11 at 16:06
  • I just suggest you one way to do it, I am sure that there are more precise solutions to do what you want to do, this was the first I came up with – Lukap Sep 13 '11 at 16:18
  • Did you find some other solution ? – Lukap Sep 16 '11 at 19:16