设置 TextView 可绘制对象的颜色

问题描述 投票:0回答:10

我正在尝试更改 Xamarin 中 TextView Drawable 的颜色。

在Java中你可以这样做:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    TextView txt = (TextView) findViewById(R.id.my_textview);
    setTextViewDrawableColor(txt, R.color.my_color);
}

private void setTextViewDrawableColor(TextView textView, int color) {
    for (Drawable drawable : textView.getCompoundDrawables()) {
        if (drawable != null) {
            drawable.setColorFilter(new PorterDuffColorFilter(getColor(color), PorterDuff.Mode.SRC_IN));
        }
    }
}

我如何在 Xamarin.Android 中执行类似的操作?

android xamarin xamarin.android
10个回答
66
投票

尝试以下解决方案

private void setTextViewDrawableColor(TextView textView, int color) {
        for (Drawable drawable : textView.getCompoundDrawables()) {
            if (drawable != null) {
                drawable.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(textView.getContext(), color), PorterDuff.Mode.SRC_IN));
            }
        }
    }

47
投票

我在 kotlin 中使用这个:

tv.getCompoundDrawables()[0].setTint(//color)

37
投票

请注意,如果您通过

android:drawableStart
android:drawableEnd
在布局文件中设置可绘制对象,而不是分别使用
android:drawableLeft
android:drawableRight
,则应使用 TextView.getCompoundDrawablesRelative()。否则你会得到空的可绘制数组。

private void setTextViewDrawableColor(TextView textView, int color) {
    for (Drawable drawable : textView.getCompoundDrawablesRelative()) {
        if (drawable != null) {
            drawable.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(textView.getContext(), color), PorterDuff.Mode.SRC_IN));
        }
    }
}

19
投票
// index of drawable
val left = 0
val start = left
val top = 1
val right = 2
val end = right
val bottm = 3

// color int
val color = Color.RED

// apply tint for target drawable
textView.compoundDrawables.getOrNull(left)?.setTint(color)

// apply tint for all drawables
textView.compoundDrawables?.forEach { it?.setTint(color) }

注意!

如果在 XML 布局中使用

android:stratDrawable
android:endDrawable
,则必须使用
textView.compoundDrawablesRelative
数组,当添加了
textView.compoundDrawables
android:leftDrawable
属性时,
android:rightDrawable
包含可绘制对象。


11
投票

我解决了这个问题,在 xml 定义中添加了这一行:

android:drawableTint="@color/red"

一个完整的例子:

        <TextView
            android:id="@+id/tv_element"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:layout_alignParentEnd="true"
            android:drawableStart="@drawable/ic_icon"
            android:drawableTint="@color/color"
            android:visibility="visible" />

10
投票

通过

TextViewCompat.setCompoundDrawableTintList(textView, colors)

对此有内置支持
val color = ContextCompat.getColor(context, R.color.foo)
val colorList = ColorStateList.valueOf(color)
TextViewCompat.setCompoundDrawableTintList(textView, colorList)

4
投票

为了

Kotlin
。对
TextView
可绘制对象使用以下扩展。它支持低于和高于 23 的 API 级别。

    private fun TextView.setTextViewDrawableColor(color: Int) {
        for (drawable in this.compoundDrawablesRelative) {
            drawable?.mutate()
            drawable?.colorFilter = PorterDuffColorFilter(
                color, PorterDuff.Mode.SRC_IN
            )
        }
    }

注意:您也可以在

RecyclerView
项目中使用此功能,它不会为每个项目
override
提供相同的颜色


4
投票

我遇到的问题是,我正在更改复合绘图的颜色,但所有颜色的其余部分都是不变的。对我来说很困惑。!!!

对我有用的解决方案是

// Pass through the each drawable and update the tint if drawable is set.
textView.compoundDrawables.filterNotNull().forEach { drawable ->
        drawable.mutate()
        drawable.setTint(drawableColor)
    }

没有

mutate()
,一切都只能部分运作。我在这里获得了更多详细信息 Drawable Mutations .

为了读者的兴趣,我在下面提供一个快速总结。

Android Drawables 是绘图容器。例如BitmapDrawable用于显示图像,ShapeDrawable用于显示形状和渐变。

Drawables are used extensively in the Android ecosystem thus they are optimized. So when views are created the different instances are spawned but the drawables associated with the view share the common state, called "Constant state". 

例如,如果可绘制对象是 BitmapDrawable,则相同的位图将用于所有相应的副本或视图。

优点:节省大量内存。

问题:因为同一个drawable在不同的视图之间共享。可绘制对象状态的任何变化(例如 Alpha、变换等)都会影响所有使用它的地方。

解决方案:在可绘制对象上调用 mutate() 方法时,可复制可绘制对象的常量状态,以允许您更改任何属性而不影响其他可绘制对象。注意:位图仍然是共享的。


3
投票

如果您想更改任何视图的可绘制对象的色调颜色(在 API 29 上测试):

private fun setTintColor(textView: TextView, color: Int) {

    DrawableCompat.setTint(DrawableCompat.wrap(textView.background).mutate(), 
    ContextCompat.getColor(this, color))

}

0
投票

我创建这样的扩展

fun TextView.setDrawableTintExt(color: Any) {
    
    when (color) {
        is String -> {
            for (drawable in this.compoundDrawables) {
                if (drawable != null) {
                    drawable.colorFilter =
                        PorterDuffColorFilter(
                            getHexColorExt(color),
                            PorterDuff.Mode.SRC_IN
                        )
                }
            }
        }
        
        is Int -> {
            for (drawable in this.compoundDrawables) {
                if (drawable != null) {
                    drawable.colorFilter =
                        PorterDuffColorFilter(
                            ContextCompat.getColor(this.context, color),
                            PorterDuff.Mode.SRC_IN
                        )
                }
            }
        }
    }
    
}
© www.soinside.com 2019 - 2024. All rights reserved.