api <21的可绘制着色


84

是否可以使api <21的可绘制着色工作?

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary" />

效果很好,但仅适用于具有API21的设备。较低api设备或AppCompat支持的任何解决方法?找不到任何东西。

Answers:


106

这样使用AppCompatImageView

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/my_appcompat_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
        android:tint="#636363"
    />

确保您appcompat-v7的应用程序中有最新的build.gradle

示例:compile 'com.android.support:appcompat-v7:25.0.0'在您应用的中build.gradle


66
来自AppCompatImageView文档:This will automatically be used when you use ImageView in your layouts. You should only need to manually use this class when writing custom views. developer.android.com/reference/android/support/v7/widget / ...因此,ImageView在布局中使用普通字体应该可以正常工作。
Nimrod Dayan'7

1
正如上面@NimrodDayan所提到的,这不是必须的。我收到有关android:tint无法在Samsung A5和Moto G上运行的报告(但是,使用appcompat-v7:23.4.0),因此在某些设备上可能无法正确替换ImageViews。
史蒂芬·基德森

@StephenKidson,我使用的是相同版本的appcompat,并且在未知品牌的设备上也遇到了相同的问题。您设法解决了吗?我想知道是否有关于此的错误报告……
Nimrod Dayan

4
这在使用appcompat-v7:25.1.0的模拟器Android 4.0上不起作用。
Peterdk

4
AppCompatImageView不能在小部件内使用。在ImageView上使用setColorFilter。
马西莫

46

您可以使用源代码来实现。以前不支持着色DrawableCompat。从支持库22.1开始,您可以执行此操作,但是您需要采用以下方式:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));

18
如果您需要在<21个API上支持着色,那么您可能要使用ContextCompat.getColor()而不是getResources().getColor()
Sevastyan Savanyuk

22

您不能简单地使用ImageView来显示Drawable吗?android:tint在较旧的API级别上可以正常工作。

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary"
    />

2
我正在使用ImageView-在其中显示图标。这些图标是我的导航抽屉中元素的一部分。导航抽屉中的选定项目具有不同的颜色,因此我为每个图标创建了着色,并为每个图标创建了选择器。我正在使用该选择器作为图标。选择者:<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@drawable/ic_home_tinted" /> <item android:drawable="@drawable/ic_home" /> </selector>
MaTTo

@Orochi看看我的回答,它直接来自Google的博客。它主要仅适用于Android 5.0+,但可能适用于运行Android 5.0之前版本的设备的某些小部件。
Jared Burrows 2015年

@Orochi您将必须创建自定义视图以“模拟”相同的效果。
Jared Burrows 2015年

1
您可以使用图像视图,将图标尽可能地设置为白色,然后使用iv.setColorFilter(yourColor,Mode.Multiply)使其变为所需的任何颜色。确保您导入android.graphics.PorterDuff.Mode
jb15613 2015年

3
这里同样的问题。遗憾的是,带有选择器的颜色不适用于api <21
Luccas

17

在此之前,有人曾问过类似的问题:https : //stackoverflow.com/a/26533340/950427

仅Android 5.0+(API 21+)支持Android Drawable着色。(它的确显示为“ At the moment this is limited to coloring the action bar and some widgets.”)。

主题化

...

设置这些属性时,AppCompat会自动将其值传播到API 21+上的框架属性。这将自动为状态栏和概述(近期)任务条目着色。

在较旧的平台上,AppCompat会尽可能模拟颜色主题。目前,这仅限于为操作栏和一些小部件着色。

小部件着色

在装有Android 5.0的设备上运行时,所有小部件都使用我们刚刚谈到的颜色主题属性进行着色。在Lollipop上允许这样做的两个主要功能是:可绘制着色和在可绘制对象中引用主题属性(格式为?attr / foo)。

AppCompat在早期版本的Android上为UI小部件的子集提供了类似的行为:

AppCompat工具栏提供的所有内容(动作模式等)EditText Spinner CheckBox单选按钮开关(使用新的android.support.v7.widget.SwitchCompat)CheckedTextView您无需执行任何特殊操作即可使这些工作,只需在您的布局将照常进行,其余部分由AppCompat负责(有一些注意事项;请参见下面的常见问题解答)。

资料来源:

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

https://chris.banes.me/2014/10/17/appcompat-v21/


为什么这被否决?这是来自官方文档。
Jared Burrows,2015年

答案已过时。ImageView现在也可以android:tint通过AppCompat进行支持,就像@Jonik的答案一样。
Vicky Chijwani

@VickyChijwani提交编辑。你的意思AppCompatImageView不是ImageView
贾里德·伯罗斯


6

要为图像着色,可以使用imageView.setColorFilter(int color)。这可以从API 8开始工作,并且可以将黑色图像着色为所需的颜色。这可以代替,setImageTintList()但仅使用android:tint也应该可以。


4

使用此NameSpace
xmlns:app =“ http://schemas.android.com/apk/res-auto”

然后您可以将每个android:tint替换为app:tint。这为我解决了这个问题。


4

我有点晚了,但是这是怎么做。

val textInput = EditText(context)

val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
drawable?.let {
    myDrawable -> DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
    textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
}

1

这将按照您的意愿进行,并且可以在所有Android版本的支持库上运行:

@JvmStatic
fun getTintedDrawable(inputDrawable: Drawable, @ColorInt color: Int): Drawable {
    val wrapDrawable = DrawableCompat.wrap(inputDrawable.mutate())
    DrawableCompat.setTint(wrapDrawable, color)
    DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN)
    return wrapDrawable
}

1

如果有人想创建新的drawable(tin1,tint2 ..),请尝试以下操作

<?xml version="1.0" encoding="utf-8"?>
<bitmap
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:src="@drawable/your_image"
  android:tint="@color/tint_color">
   </bitmap>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.