Well guys, I have found a tricky solution for this.
However, I hope Android implements soon a clean and direct way to do this.
Lets see the solutions:
For the case of setting gradient programatically to an image, I redrew the image into imageview.
The method below casts imageview to bitmap, setting height and width manually (these values must keep the aspect ratio of the original asset in order to not modify the original asset) and passing gradient colors. Colors is an object I created which contains to strings (gradientStart and gradientEnd)
fun setImageWithGradient(imageview: ImageView, width : Int, height : Int, colors: Colors) {
val myBitmap = (imageview.drawable).toBitmap(width, height)
val newBitmap = addGradient(myBitmap, colors)
imageview.setImageDrawable(BitmapDrawable(resources, newBitmap))
}
The method above redraws the bitmap received, applies the gradient (colors object I mentioned above) and return the bitmap (asset with the gradient applied) Then you may set this bitmap returned into the imageview desired.
fun addGradient(originalBitmap: Bitmap, colors: Colors): Bitmap? {
val width = originalBitmap.width
val height = originalBitmap.height
val updatedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(updatedBitmap)
canvas.drawBitmap(originalBitmap, 0.toFloat(), 0.toFloat(), null)
val paint = Paint()
val shader = LinearGradient(0.toFloat(), 0.toFloat(), 0.toFloat(), height.toFloat(), Color.parseColor(colors.gradientStart), Color.parseColor(colors.gradientEnd), Shader.TileMode.CLAMP)
paint.shader = shader
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawRect(0.toFloat(), 0.toFloat(), width.toFloat(), height.toFloat(), paint)
return updatedBitmap
}
For the case of applying gradient to CardView background, I didnt find different way but adding a RelativeLayout inside the CardView, with size matching parent's one. Then, applying the gradient not to CardView's background, but to RelativeLayout's background.
The method below is the one doing this:
private fun setMedalRankingColor(gradientColors: Colors) {
val color = intArrayOf(Color.parseColor(gradientColors.gradientStart), Color.parseColor(gradientColors.gradientEnd))
val gradient = GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, color)
gradient.cornerRadius = 0f
binding.medal.background = gradient
}
I hope helps someone, and feel fre to share your solution if better than this.
CHEERS!