Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android transparent text

I need to display a TextView over a gradient background. The TextView itself should have a plain white background, and the text should be transparent.

However, setting a transparent color (#00000000) to the text doesn't work: it only shows a white rectangle, the background doesn't show up where the text is (the text takes the same color as the TextView background).

How can I display a transparent text with a background color on my TextView?

like image 529
Marc Plano-Lesay Avatar asked Nov 14 '13 09:11

Marc Plano-Lesay


People also ask

How do I make text transparent on Android?

Set the Alpha value to 00 (hex) to make any color fully opaque. Set the Alpha value to ff (hex) to make it transparent (the color doesn't matter anymore).

What is transparent color in Android?

TRANSPARENT (which represents the same thing as @android:color/transparent ) is equal to 0 . The hex representation of 0 is #00000000 , which means that Color. TRANSPARENT is essentially a completely transparent Color.


2 Answers

Update, Jan 30, 2016

I made a small library and written a blog post out of this answer, so you don't need to copy and paste code and I do the maintenance for you. :)

Use the view in xml as:

<it.gilvegliach.android.transparenttexttextview.TransparentTextTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/view_bg"
    android:text="Hello World" />

Gradle dependency:

 compile 'it.gilvegliach.android:transparent-text-textview:1.0.3'

Original Answer

This is how you can achieve that effect:

  1. you render the text over a transparent background on a bitmap
  2. you use that bitmap to clip the text shape out of the solid white background

Here is a simple subclass of TextView that does that.

final public class SeeThroughTextView extends TextView
{
    Bitmap mMaskBitmap;
    Canvas mMaskCanvas;
    Paint mPaint;

    Drawable mBackground;
    Bitmap mBackgroundBitmap;
    Canvas mBackgroundCanvas;
    boolean mSetBoundsOnSizeAvailable = false;

    public SeeThroughTextView(Context context)
    {
        super(context);

        mPaint = new Paint();
        mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
        super.setTextColor(Color.BLACK);
        super.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    }

    @Override
    @Deprecated
    public void setBackgroundDrawable(Drawable bg)
    {
        mBackground = bg;
        int w = bg.getIntrinsicWidth();
        int h = bg.getIntrinsicHeight();

        // Drawable has no dimensions, retrieve View's dimensions
        if (w == -1 || h == -1)
        {
            w = getWidth();
            h = getHeight();
        }

        // Layout has not run
        if (w == 0 || h == 0)
        {
            mSetBoundsOnSizeAvailable = true;
            return;
        }

        mBackground.setBounds(0, 0, w, h);
        invalidate();
    }

    @Override
    public void setBackgroundColor(int color)
    {
        setBackgroundDrawable(new ColorDrawable(color));
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        mBackgroundBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mBackgroundCanvas = new Canvas(mBackgroundBitmap);
        mMaskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mMaskCanvas = new Canvas(mMaskBitmap);

        if (mSetBoundsOnSizeAvailable)
        {
            mBackground.setBounds(0, 0, w, h);
            mSetBoundsOnSizeAvailable = false;
        }
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        // Draw background
        mBackground.draw(mBackgroundCanvas);

        // Draw mask
        mMaskCanvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
        super.onDraw(mMaskCanvas);

        mBackgroundCanvas.drawBitmap(mMaskBitmap, 0.f, 0.f, mPaint);
        canvas.drawBitmap(mBackgroundBitmap, 0.f, 0.f, null);
    }
}

Example screenshot: indigo pattern for activity background, pink solid fill for TextView background.

This works both for solid color backgrounds and general drawables. Anyway, this is only a BASIC implementation, some feature such as tiling are not supported.

like image 130
Gil Vegliach Avatar answered Sep 28 '22 08:09

Gil Vegliach


I have not tried this, but you might be able to do this by (against all documentation advice) getting the TextPaint through TextView.getTextPaint() and call setXferMode(new PorterDuffXferMode(PorterDuff.Mode.MULTIPLY)), in order to clear the alpha bits on the background while rendering.

Otherwise, implement your own text view where you are in full control of the rendering.

like image 25
David Burström Avatar answered Sep 28 '22 09:09

David Burström