【问题标题】:Change tint color of images which below overlay view更改覆盖视图下方的图像的色调颜色
【发布时间】:2019-11-01 10:47:30
【问题描述】:

我有一个包含很多图像的滚动视图。我想实现一个高亮区域,它改变它下面所有视图的颜色(只有区域正下方的部分视图)

这是布局,vOverlayColor 是我要设置叠加颜色的视图。

<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>

你有什么建议吗?

【问题讨论】:

  • 请试试我的答案

标签: android android-layout android-view android-constraintlayout


【解决方案1】:

此处 measureAndSetup 函数循环遍历线性布局内的所有视图(它是滚动视图的直接子视图)并找到与覆盖视图相交的区域并适当地应用 changeColor 函数。 更改颜色函数获取imageview内的位图,如果像素在相交区域内,则将其着色为蓝色(使用常量,因为imageview尺寸和运行时查询的位图尺寸不同),其余区域为黑色。

完全超出覆盖区域的视图被染成黑色。

看看我的代码并尝试一下

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>

【讨论】:

    【解决方案2】:

    试试这个:

    Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.my_drawable); 
    Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
    DrawableCompat.setTint(wrappedDrawable, Color.blue);
    

    希望这会有所帮助!

    【讨论】:

    • 感谢您的回答。不知道你有没有认真准备好我的问题,但是我要实现的是一个覆盖视图,它可以在它下面的所有ImageView上添加特定的颜色;不单独为每个 ImageView 设置颜色
    • 请试试这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 2012-10-22
    • 1970-01-01
    相关资源
    最近更新 更多