Здесь функция measureAndSetup зацикливается на всех представлениях внутри линейного макета (который является прямым потомком scrollview) и находит пересекающуюся область с представлением наложения и соответствующим образом применяет функцию changeColor. Функция изменения цвета получает растровое изображение внутри изображения, окрашивает его в синий цвет, если пиксель находится внутри пересекающейся области (константа используется в качестве измерения просмотра изображения и размер растрового изображения, запрашиваемый во время выполнения, отличается), остальные области окрашены в черный цвет.
Виды, полностью выходящие за пределы области наложения, окрашены в черный цвет.
Посмотрите на мой код и попробуйте
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)
}
}
А вот мой макет 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>