I have not provided any code cause i have no idea how to implement this. I want to partially tint my image view in android java with another color at the bottom like the on the picture. Please help.
-
This is similar question to this [https://stackoverflow.com/q/31959829/11984583](https://stackoverflow.com/q/31959829/11984583) check this for – Khamidjon Khamidov May 27 '20 at 23:37
-
Its deep than what meets the eye, if you try to implement it – Talent Gramzrah May 28 '20 at 01:25
2 Answers
First off create a gradient xml file in the drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient android:startColor="#000" android:angle="90"/>
</shape>
For API 23 and above:
In your layout where the ImageView is defined just add the attribute android:foreground = "@drawable/gradient"
. This simply lays the gradient on top of the ImageView.
Simple but not advised
You could just add another ImageView ontop of the one which displays the Image. Then the ImageView laid on top would have set the android:src = "@drawable/gradient"
attribute set. This does work but I would not advise it. Yes it is simple but using ViewOverlay (as we will see in the next solution) is more efficent.
Otherwise
It's getting a bit more complicated here. First off you must register a ViewTreeObserver with addOnGlobalLayoutListener and implement the method OnGlobalLayout. Then you simply get the gradient drawable and apply the bounds of the ImageView (which will be its parent to it). In the end just set the drawable as ViewOverlay of the ImageView.
Honestly initially I thought it will be enough to write this but I am realizing that it's really complicated. So here is the ugly Kotlin version of it:
ivImage.viewTreeObserver.addOnGlobalLayoutListener {
val drawable = resources.getDrawable(R.drawable.gradient).apply {
bounds = Rect(0, 0, ivImage.width, ivImage.height)
}
ivImage.overlay.add(drawable)
}
This would be the Java version (also not beautiful code):
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.gradient);
drawable.setBounds(0, 0, imageView.getWidth(), imageView.getHeight());
imageView.getOverlay().add(drawable);
}
});
IMPORTANT: Do not forger to unregister your OnGlobalLayoutListener.
This can be done in Java inside the onGlobalLayout method like this: imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

- 4,096
- 3
- 22
- 28
The way you do it is with FrameLayout(Frame Layout helps you to place layouts one over the other). Inside frame Layout first, put ImageView and then a normal View with the background as gradient_transparent_black.xml (So Basically view is above the ImageView).
Following is an example: (You can make the View height whatever you want I have it here as 80dp. Also in my example, FrameLayout is inside a ConstraintLayout)
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toOf="@+id/imageView3"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/image_you_want" />
<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="bottom"
android:background="@drawable/gradient_transparent_black"
android:clickable="false" />
</FrameLayout>
gradient_transparent_black.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#000000"
android:endColor="#00FFFFFF"
android:angle="90"
android:dither="true"
/>
</shape>

- 383
- 2
- 11
-
A relative layout you can place views on top of another again. Okay i will try and get back to you – Talent Gramzrah May 28 '20 at 01:28
-
I would recommend FrameLayout since its purpose is to place objects one over the other You probably know but just as supplementary info : The order of elements inside FrameLayout determines the z position, the first element at the bottom and the last element is at the top. Use **gravity** to position elements wrt to parent. Hope it helps, any doubt feel free to ask in the comments. – Saharsh May 29 '20 at 20:03