'Android TextView shadow doesn't work when Radius set to 0

I need to draw a shadow on a title, without any blur, like in this image: text with shadow, shadowRadius = 0

My problem is that as soon as I set the shadowRadius to 0, the shadow doesn't appear anymore.

Here's the code I'm using, in my style.xml

<style name="navigationTitleWithShadow">
    <item name="android:textAllCaps">true</item>
    <item name="android:textColor">@color/navigationTitleForegroundColor</item>
    <item name="android:shadowColor">@color/navigationTitleShadowColor</item>
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item>
    <item name="android:shadowRadius">0</item>
</style>

And in the layout :

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/nav_header_vertical_spacing"

    android:text="@string/menuTableViewController_navigationTitle"
    android:textAppearance="@style/navigationTitleWithShadow" />

Any idea how to have this 0 shadowRadius ?



Solution 1:[1]

I found a solution, subclassing TextView, overriding method onDraw(). Here's my code:

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

    if ( getShadowColor() != 0 && getShadowRadius() == 0 ) {

        Paint paint = this.getPaint();
        paint.setColor(getShadowColor());

        paint.setTextAlign(Paint.Align.CENTER);

        int xPos = (canvas.getWidth() / 2);
        int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() +
                paint.ascent()) / 2));

        // Draw the shadow text first, so it appears below
        canvas.drawText(getText().toString().toUpperCase(), xPos + getShadowDx(), yPos + getShadowDy(), paint);

        paint.setColor(getCurrentTextColor());

        // Draw the main text on top of it
        canvas.drawText(getText().toString().toUpperCase(), xPos, yPos, paint);

    } else {
        super.onDraw(canvas);
    }

}

It works well, although I'm not sure why I need the setTextAlign, but without it my text is misplaced, on the right.

Solution 2:[2]

While not stated in TextView.shadowRadius, the Paint.setShadowLayer description states that

If radius is 0, then the shadow layer is removed.

What seems to be a good idea when having the shadow completely hidden behind the text, but as shadow can be offset and the text can be semi transparent it can hide wanted shadows.

Using a min blur of 0.1f is not the same but works out in my case.

paint.setShadowLayer(
    max(blur, 0.1f),
    dx,
    dy,
    color
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Olivier Berni
Solution 2 xian