PorterDuff.Mode equivalent for edge fading

1.3k Views Asked by At

I want to programatically render the edge fading of a TextView. By which mode I can create a true alpha gradient?

A real edge fading should smoothly reduce the transparency (no overlay gradient hack) from 1.0 to 0.0 so that the top view fade into background view.

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

    int y = 0;
    int height = 300;
    int width = getWidth();

    LinearGradient shader = new LinearGradient(width / 2, y, width / 2, y + height, 0xff000000, 0x0000000, Shader.TileMode.CLAMP);

    Paint p = new Paint();
    p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XXX)); // Which mode works?
    p.setShader(shader);

    canvas.drawRect(0, y, width, y + height, p);
}

I tried all the combinations and none of them worked? Is it impossible to do so?

1

There are 1 best solutions below

0
On

Here is my solution with an ImageView. I use a GradientDrawable for the alpha.

Activity:

@Override
protected void onCreate (Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    getWindow().setBackgroundDrawableResource(R.drawable.background);
    GradientImageView giv = new GradientImageView(this);
    giv.setImageResource(R.drawable.bttf);
    giv.setScaleType(ImageView.ScaleType.CENTER_CROP);
    setContentView(giv);

}


class GradientImageView extends ImageView
{
    Drawable mDrawableMask;
    Paint    mPaintMask;
    Bitmap   mOriginal, mBitmapMask;
    Canvas mCanvasOriginal, mCanvasMask;


    public GradientImageView (final Context context)
    {
        super(context);
        if (android.os.Build.VERSION.SDK_INT >= 11)
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        mDrawableMask = getResources().getDrawable(R.drawable.gradient);
        mPaintMask = new Paint();
        mPaintMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

    protected void setMask (Drawable mask)
    {
        mDrawableMask = mask;
        mBitmapMask = null;

    }

    @Override
    protected void onDraw (final Canvas canvas)
    {
        if (mOriginal == null)
        {
            mOriginal = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            mCanvasOriginal = new Canvas(mOriginal);
        }

        super.onDraw(mCanvasOriginal);


        if (mBitmapMask == null)
        {
            mBitmapMask = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            mCanvasMask = new Canvas(mBitmapMask);
            mDrawableMask.setBounds(0, 0, getWidth(), getHeight());
            mDrawableMask.draw(mCanvasMask);
        }

        canvas.drawBitmap(mOriginal, 0, 0, null);
        canvas.drawBitmap(mBitmapMask, 0, 0, mPaintMask);
    }
}

gradient.xml

<?xml version="1.0" encoding="utf-8"?>

<gradient
    android:angle="-90"
    android:centerColor="@android:color/transparent"
    android:centerY="0.5"
    android:endColor="@android:color/black"
    android:startColor="@android:color/transparent" />

values.xml

 <drawable name="background">#FF0000</drawable>

The result (activity background is Red) Yeah !