Android in fact quite functional need gradient text, graphics effect. For example, when scrolling lyrics, Toutiao TAB slides, the text has a gradual change process

Before the interview, I was asked how to make this cropped waveform.

Today did this rolling lyrics, the idea should be the same.

Center the text

Painting guides

Canvas.drawline () is the drawLine method

Parameters: As the name suggests

There’s nothing to tell

Writing in the middle

Canvas.drawtext () is the method to drawText

Baseline seems like nothing to say, but why is baseline at Y point?? There is a big hole here, the text is drawn not from the bottom left corner of the text, but from this baseline.

baseline

The red line above is the baseline, from which the text is drawn, and it ensures that most of the text is aligned, like the horizontal lines in a pinyin grid. The baseline is + (positive) and – (negative) because the Android coordinate system is down.

The top and bottom

The upper and lower boundaries of all characters and symbols. Top is negative, bottom is positive. The reason is that the baseline is the coordinate system

Ascent and desecnt

The upper and lower boundaries of most characters (excluding special characters, symbols, some Tibetan, Latin, etc.). Ascent is – (negative) and desecnt is + (positive) because it is based on the baseline coordinate system

Desecnt +ascent /2: Ascent height: (desecnt – ascent

These text messages are in the paintmetrics class

   /** Draw the middle text */
    Paint paintText;
    private void drawText(final Canvas canvas){
        canvas.save();
        if (paintText == null){
            paintText = new Paint();
            paintText.setTextSize(100);
            paintText.setColor(Color.BLACK);
            paintText.setAntiAlias(true);
        }
        // You want the text to be truly centered
        // Width of direct screen /2 + paint.align.CENTER will do or half the width of text
        int xCenter = (int) (getWidth()/2 - paintText.measureText(text)/2);
        paintText.setTextAlign(Paint.Align.LEFT);

        // High minus the baseline /2
        Paint.FontMetrics fontMetrics = paintText.getFontMetrics();
        int yCenter = (int) (getHeight()/2 - (fontMetrics.ascent + fontMetrics.descent)/2);
        canvas.drawText(text,xCenter,yCenter,paintText);
        canvas.restore();
    }
Copy the code

Draw clipped gradient text

Canvas.save () and canvas.restore() are paired, otherwise restore() will report an error if there is no save. They are used for preservation and restoration. Think of it as a photoshop layer, and a group is a layer.

canvas.clipRect(rect); Cropping, you can crop the canvas, you can think of it as cropping in Photoshop

Ideas:

Draw one layer with black text below, one layer with colored text above, then crop the top layer to show only the percentage of the image that needs to be displayed.

  /** Draw clipped red text */
    Paint paintText1;
    private void drawText1(final Canvas canvas){
        canvas.save();
        int withText = (int) paintText.measureText(text);
        int xCenter = (int) (getWidth()/2 - withText/2);

        if (paintText1 == null){
            paintText1 = new Paint();
            paintText1.setTextSize(100);
            paintText1.setTextAlign(Paint.Align.LEFT);
            
            // Set gradient
            int [] colors = {Color.RED,Color.GREEN, Color.BLUE};
            float[] position = {0f, 0.7f, 1.0f};
            LinearGradient linearGradient = new LinearGradient(xCenter,0,xCenter+withText,0,colors,position, Shader.TileMode.CLAMP);
            // Set the shader
            paintText1.setShader(linearGradient);

            paintText1.setAntiAlias(true);
        }

        Paint.FontMetrics fontMetrics = paintText1.getFontMetrics();
        int yCenter = (int) (getHeight()/2 - (fontMetrics.ascent + fontMetrics.descent)/2);
        
        < percentage > < percentage > < percentage > < percentage > < percentage > < percentage > < percentage > < percentage
        Rect rect = new Rect(xCenter,0, (int) (xCenter + percentage * withText),getHeight());
        canvas.clipRect(rect);
        canvas.drawText(text,xCenter,yCenter,paintText1);
        canvas.restore();
    }

Copy the code

Invalidate (), draw ()

Every time you pass in a different percentage, you have to redraw it

  public void changeColor(float percentage){
        this.percentage=percentage;
        invalidate();
    }
Copy the code