Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextView adding gradient AND shadow

I have a problem. I would like to have a textview with a gradient as color. And a black shadow behind it. The problem is that the shadow is using the color of the gradient in stead of using the called color (Color.BLACK)

My code is: numberTextView = (TextView)findViewById(R.id.something);

    Shader textShaderTop = new LinearGradient(0, 30, 0, 60,
                new int[]{Color.parseColor("#A6A6A6"), Color.parseColor("#E8E8E8"), Color.parseColor("#A6A6A6")},
                new float[]{0, 0.5f, 1}, TileMode.CLAMP);
    numberTextView.getPaint().setShader(textShaderTop);

    numberTextView.setShadowLayer(
              0.1f,   //float radius
              20f,  //float dx
              20f,  //float dy 
              Color.BLACK //this is not black on the screen, but it uses the gradient color!?
              );

Does anybody knows what to do

like image 623
w.donk Avatar asked Sep 07 '11 08:09

w.donk


2 Answers

I had exactly the same problem. I managed to fix it by extending TextView and overriding onDraw method. Here is how it looks like

@Override
protected void onDraw(Canvas canvas) {
    // draw the shadow
    getPaint().setShadowLayer(1, 1, 1, 0xbf000000); // or whatever shadow you use
    getPaint().setShader(null);
    super.onDraw(canvas);

    // draw the gradient filled text
    getPaint().clearShadowLayer();
    getPaint().setShader(new LinearGradient(0, getHeight(), 0, 0, 0xffacacac, 0xffffffff, TileMode.CLAMP)); // or whatever gradient/shader you use
    super.onDraw(canvas);
}

However this method probably won't work if you want to use colors with transparency in your gradient.

like image 69
sidon Avatar answered Sep 27 '22 16:09

sidon


Thank you for sidon's answer. It helped me.

And I add this answer because I found a way to use colors with transparency in gradient. So, please refer to sidon's answer first and upvote his one.

I found below at "setShadowLayer" Method Description from here.

The alpha of the shadow will be the paint's alpha if the shadow color is opaque, or the alpha from the shadow color if not.

So, point is shadowColor must be not opaque to use colors with transparency in gradient.

Here is code.

@Override
protected void onDraw(Canvas canvas) {
    // draw the shadow
    getPaint().setShader(null);
    setTextColor(0x00ffffff); // set the paint's alpha by 00
    getPaint().setShadowLayer(3.0f, 1.5f, 1.8f, shadowColor); // shadowColor must be not opaque
    super.onDraw(canvas);

    // draw the gradient filled text
    getPaint().clearShadowLayer();
    setTextColor(0xffffffff); // set the paint's alpha by ff
    getPaint().setShader(new LinearGradient(0, 0, getWidth(), getHeight(), 0x7fff8809, 0x7f09ffff, Shader.TileMode.CLAMP)); // or whatever gradient/shader you use
    super.onDraw(canvas);
}

If shadowColor is opaque, you may change it as not opaque by reduce the alpha by one.

if((shadowColor >>> 24) == 0xff)
    shadowColor &= 0xfeffffff;

Thank you once again for sidon's answer.

2018-12-16 Edit:

If you have the same alpha value about colors, below code would better.

public class TextView_Gradient extends TextView {

    public TextView_Gradient(Context context) {
        super(context);
        setTextColor(0x3fffffff); // set the paint's alpha by 3f
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // draw the shadow
        getPaint().setShader(null);
        // shadowColor must be opaque.
        getPaint().setShadowLayer(3.0f, 1.5f, 1.8f, shadowColor);
        super.onDraw(canvas);

        // draw the gradient filled text
        getPaint().clearShadowLayer();
        // gradient colors must be opaque, too.
        getPaint().setShader(new LinearGradient(0, 0, getWidth(), getHeight(), 0xffff8809, 0xff09ffff, Shader.TileMode.CLAMP));
        super.onDraw(canvas);
    }
}

Because the alpha of the shadow will be the paint's alpha if the shadow color is opaque. And the alpha of the gradient colors is the paint's alpha if the alpha of the gradient colors are ff(opaque).

(Or the final alpha of text can be scaled again by the gradient color's alpha value provided that the paint's alpha is ff.)

Output: enter image description here

like image 28
SG H Avatar answered Sep 27 '22 16:09

SG H