-2

I want to have an imageView that is fully visible at the top, but further down it fades out, resulting in being fully transparent in the bottom. How do I achieve this?

zorigo
  • 9
  • 3
  • You probably can use a custom image view, using a PorterDuff xfermode (draw the image using super.onDraw and then draw a alpha linear gradient with an xfermode) I don't have access to a computer for a while, but you can search for them – Amin Jan 07 '22 at 01:56
  • 1
    Thank you, exactly the kind of nod in the right direction I hoped for. I will look into your leads. – zorigo Jan 07 '22 at 01:58
  • You're welcome! Also, if real transparency is not what you need (you really don't want to see beneath the image) you can simply draw a linear white (you background color actually) gradient over the image, to mimic what real transparency would do, but I guess xfermode should work fine and is a better choice – Amin Jan 07 '22 at 02:03

1 Answers1

0

I have a solution for this, but it is not perfect

class LinearGradientView : View {
    var bitmap: Bitmap
    private val paint = Paint()

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(MeasureSpec.makeMeasureSpec(bitmap.width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(bitmap.height, MeasureSpec.EXACTLY))
    }

    override fun onDraw(canvas: Canvas) {
        val shaderA: Shader = LinearGradient(0F, 0F, 0F, bitmap.height.toFloat(), -0x1, 0x00ffffff, Shader.TileMode.CLAMP)
        val shaderB: Shader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        paint.shader = ComposeShader(shaderA, shaderB, PorterDuff.Mode.SRC_IN)
        canvas.drawRect(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat(), paint)
    }

    init {
        bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.ktor)
    }
}

The key is to leverage ComposeShader with LinearGradient and BitmapShader.

enter image description here

reference:
Android extends imageView gradient transparent vertical linear from input bitmap
Drawing a Bitmap to a Canvas with an alpha gradient

PangoSea
  • 591
  • 3
  • 11