Try to play with raster images:
- Detect bounds of text using
Paint.getTextBounds()
method
- Create transparent
Bitmap
with such metrics (W + H) x H
(you may use Bitmap.Config.ALPHA_8
to optimize memory usage)
- Draw text on this
Bitmap
at 0x0
position
- Copy first row of
Bitmap
into new one with original width, but with height of 1px
- Iterate over the
Y-axis
of Bitmap
(from top to bottom) and draw single-line Bitmap
with the corresponding offset by X-axis
(you will overdraw some transparent pixels)
- Now you have the top-part of your shadow
- Draw the bottom part using same technique, but choosing last row of this
Bitmap
This algorithm may be optimized if you detect, that all pixels in last row have the same color (full shadow).
UPDATE 1
I achieved such result using this quick solution:

MainActivity.java
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
LongShadowTextView longShadow = new LongShadowTextView(this);
longShadow.setText("Hello World");
setContentView(longShadow);
}
}
LongShadowTextView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.View;
public class LongShadowTextView extends View {
private Bitmap mBitmap;
private String mText;
public LongShadowTextView(Context context) {
super(context);
}
public void setText(String text) {
Paint paint = new Paint();
// TODO provide setters for these values
paint.setColor(Color.BLACK);
paint.setTextSize(142);
Rect rect = new Rect();
paint.getTextBounds(text, 0, text.length(), rect);
Bitmap bitmap = Bitmap.createBitmap(rect.width() + rect.height(), rect.height(), Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, 0, rect.height(), paint);
Rect src = new Rect();
RectF dst = new RectF();
int w = bitmap.getWidth();
int h = bitmap.getHeight();
src.left = 0;
src.right = w;
for (int i = 0; i < h; ++i) {
src.top = i;
src.bottom = i + 1;
dst.left = 1;
dst.top = i + 1;
dst.right = 1 + w;
dst.bottom = i + 2;
canvas.drawBitmap(bitmap, src, dst, null);
}
mText = text;
mBitmap = bitmap;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, null);
}
}
UPDATE 2
Here is final result which I achieved. Clone this demo from github.
