【问题标题】:Android transparent text安卓透明文字
【发布时间】:2013-11-27 06:03:26
【问题描述】:

我需要在渐变背景上显示TextViewTextView 本身应该有纯白色背景,并且文本应该是透明的。

但是,为文本设置透明颜色 (#00000000) 不起作用:它只显示一个白色矩形,背景不显示文本所在的位置(文本采用与 @987654323 相同的颜色@ 背景)。

如何在TextView 上显示带有背景色的透明文本?

【问题讨论】:

  • 您似乎希望文本通过并获得渐变背景的颜色。然后把文字的颜色设置为渐变的颜色,是不是也给你一样的结果?!
  • 否,因为渐变显示为Activity 背景。文本应仅显示渐变的一小部分,因为它不会占用整个 Activity 大小。
  • Osama 是对的。简单的解决方案是将文本颜色设置为渐变颜色。在这里,您的 textview 似乎是透明的。这就是你看到白色背景的原因。确认一下,你可以设置红色看看,它会显示红色。
  • 正如我所说,不,这不是解决方案。在背景(Activity's)上,渐变分布在整个屏幕上。如果我将渐变设置为我的文本颜色,它将仅在 TextView 中传播。差异清晰可见,因为渐变中的每种颜色都显示在更小的区域上。

标签: android textview transparency


【解决方案1】:

2016 年 1 月 30 日更新

我做了一个小library并用这个答案写了一个blog post,所以你不需要复制和粘贴代码,我为你做维护。 :)

使用xml中的视图为:

<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 依赖:

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

原答案

这是实现该效果的方法:

  1. 您在位图的透明背景上渲染文本
  2. 您使用该位图从纯白色背景中裁剪出文本形状

这是一个简单的 TextView 子类,它可以做到这一点。

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);
    }
}

示例截图:活动背景为靛蓝图案,TextView 背景为粉红色实心填充。

这适用于纯色背景和一般可绘制对象。无论如何,这只是一个 BASIC 实现,不支持平铺等一些功能。

【讨论】:

  • 这几乎是完美的,谢谢。但是,您正在覆盖 setBackgroundColor 而不是使用 TextView 背景。你有什么方法可以重用TextView 背景可绘制对象吗?
  • 我试过了,但没能成功。我还在努力。顺便说一句,我更新了代码,所以在设置背景颜色后调用 invalidate() 。 (否则不保证触发抽奖循环)
  • 好的。我也在努力。如果我设法让它工作,我会在这里发帖。再次感谢您的代码:-)
  • 好吧,对不起,它确实有效。我试图直接在构造函数中更改背景颜色来测试,坏主意。我会努力改进它,如果我有更好的,我会分享一些代码。同时,这是给我一个工作结果的唯一答案,因此我接受它。再次感谢!
  • 很棒的图书馆!谢谢!
【解决方案2】:

对你的 Textview 背景做任何事情,但要让 Textview 上的文本变得透明,请使用下面的代码。

<TextView
    ...
    ...
    android:textColor="#00000000" >
</TextView>

希望对你有帮助...

【讨论】:

  • 我一开始就是这样尝试的。可悲的是,TextView 背景已经在文本本身下方,因此“通过”文本显示的是背景,而不是背后的 View
【解决方案3】:

将此代码添加到您的 textview 标签:

 android:background="#07000000"

【讨论】:

  • 这不是我想要的:我希望我的TextView 是纯白色的,并且可以看穿它只显示文本的位置。
【解决方案4】:

我没有尝试过,但您可以通过(不顾所有文档建议)通过 TextView.getTextPaint() 获取 TextPaint 并按顺序调用 setXferMode(new PorterDuffXferMode(PorterDuff.Mode.MULTIPLY)) 来做到这一点在渲染时清除背景上的 alpha 位。

否则,实现您自己的文本视图,您可以完全控制渲染。

【讨论】:

  • 设置MULTIPLY 模式不起作用:每个字符都被黑色方块包围。这是有和没有它的唯一变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多