I have a scroll view which contains a lot of images. I want to implement a highlight zone which changes color of all views below it (only part of view which right below the zone)
Here are the layout, vOverlayColor
is the view that I want to set overlay color.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:tint="@color/colorGreyDark"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:tint="@color/colorGreyDark"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:tint="@color/colorGreyDark"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:tint="@color/colorGreyDark"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:tint="@color/colorGreyDark"
tools:ignore="ContentDescription" />
</LinearLayout>
</ScrollView>
<View
android:id="@+id/vOverlayColor"
android:layout_width="match_parent"
android:layout_height="120dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Do you have any suggestion?
Here measureAndSetup function loops over all views inside Linear layout (which is the direct child of scrollview) and finds the intersecting region with the overlay view and applies the changeColor function appropriately. The change color function gets the bitmap inside imageview, colors it to blue if the pixel is inside the intersecting region (a constant is used as the imageview dimension and bitmap dimension queried at runtime are different), rest areas are colored black.
The views completely out of overlay area are tinted black.
Have a look at my code and give a try
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.forEachIndexed
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sv.viewTreeObserver.addOnGlobalLayoutListener {
measureAndSetup()
}
sv.getViewTreeObserver().addOnScrollChangedListener {
measureAndSetup()
}
}
private fun measureAndSetup() {
val top = sv.scrollY + vOverlayColor.top
val bottom = top + vOverlayColor.height
ll01.forEachIndexed { index, view ->
val iv = view as ImageView
if (view.bottom >= top && view.top <= top) {
if (view.bottom <= bottom) {
//starts on top and ends inside overlay
changeColor(iv, top - view.top, view.height)
} else {
// starts on top and ends below
changeColor(iv, top - view.top, top - view.top +
vOverlayColor.height)
}
} else if (view.top >= top && view.bottom <= bottom) {
//starts inside overlay and ends inside
changeColor(iv, 0, view.height)
} else if (view.top <= bottom && view.top >= top && view.bottom >
bottom) {
//starts inside and ends outside
changeColor(iv, 0, view.height - (view.bottom - bottom))
} else {
iv.setImageDrawable(iv.drawable.apply {
setTint(Color.BLACK)
})
}
}
}
fun changeColor(view: ImageView, startHt: Int, endHt: Int) {
val bitmapDrawable = view.getDrawable() as BitmapDrawable
val bitmap = bitmapDrawable.bitmap
val bmCopy = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), bitmap.getConfig())
val const = view.height / bitmap.height
for (i in 0 until bitmap.getWidth()) {
for (j in 0 until bitmap.getHeight()) {
if (j * const > startHt && j * const < endHt) {
val p = bitmap.getPixel(i, j)
bmCopy.setPixel(i, j, Color.argb(Color.alpha(p), 0, 0,
255))
} else {
val p = bitmap.getPixel(i, j)
bmCopy.setPixel(i, j, Color.argb(Color.alpha(p), 0, 0, 0))
}
}
}
view.setImageBitmap(bmCopy)
}
}
And here is my layout xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sv"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/ll01">
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="@+id/iv"
android:layout_margin="20dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="20dp"
android:src="@drawable/ic_delete"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_margin="20dp"
android:src="@drawable/ic_delete"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/ic_delete"
android:layout_margin="20dp"
tools:ignore="ContentDescription" />
</LinearLayout>
</ScrollView>
<View
android:id="@+id/vOverlayColor"
android:layout_width="match_parent"
android:layout_height="180dp"
android:foreground="@color/colorPrimaryDark"
android:alpha="0.2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With