Android transparent text

后端 未结 5 2046
野性不改
野性不改 2020-12-14 12:00

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

5条回答
  •  隐瞒了意图╮
    2020-12-14 13:05

    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:

    
    

    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.

提交回复
热议问题