Android 以编程方式着色支持向量

Android 以编程方式着色支持向量,android,android-appcompat,android-vectordrawable,Android,Android Appcompat,Android Vectordrawable,Android Studio 2.1版,gradle 2.1.0版,如果发现任何误解,请纠正我:) 我对支持库23.3.0中的支持向量感到困惑。具体来说,我想做的是以编程方式着色一个图像按钮,它的src是一个可绘制的向量。据我所知,这是不可能的前棒棒糖现在 我读过几篇关于这些变化的相关文章: : 从Android Support Library 23.3.0开始,只能通过app:srcCompat或setImageResource()加载支持向量绘图 以上是否意味着vector Xml只能通过s

Android Studio 2.1版,gradle 2.1.0版,如果发现任何误解,请纠正我:)

我对支持库23.3.0中的支持向量感到困惑。具体来说,我想做的是以编程方式着色一个图像按钮,它的src是一个可绘制的向量。据我所知,这是不可能的前棒棒糖现在

我读过几篇关于这些变化的相关文章: :

从Android Support Library 23.3.0开始,只能通过app:srcCompat或setImageResource()加载支持向量绘图

以上是否意味着vector Xml只能通过srccomat或setImageResource()在棒棒糖前使用,因此不能动态着色

这是我的基本图像按钮:

<ImageButton
    android:id="@+id/nav_header_exit_community_button"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:background="@null"/>
尝试此预棒棒糖会引发:
android.content.res.Resources$NotFoundException:File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID#0x7f0200bf

也只适用于棒棒糖及以上

这会在预棒棒糖上引发相同的错误

但是,如果我删除了所指出的vectorDrawables.useSupportLibrary=true,目的是让构建工具自动为棒棒糖前的设备生成PNG,PNG不会在棒棒糖前着色,因此我回到了原点

我也尝试过通过
srcCompat
指定向量,并通过编程方式检索它,但我认为我无法实现这一点,即使它可以在棒棒糖后使用
src
指定向量

因此,23.3.0的情况似乎是:

  • 棒棒糖后:
    src
    srcCompat
    接受向量,只能接受
    src
    从视图中检索为可绘制,以编程方式着色。 使用getDrawable可以在代码中引用向量,并且 可以着色

  • Pre-Lollipop:srcCompat只能接受向量,无法检索 从视图以编程方式进行着色<代码>设置图像资源可以 接受向量,但仅当向量Drawables.useSupportLibrary=false且着色不起作用时才接受。类似地,代码中的引用向量也不是 可能的情况下,除非
    vectorDrawables.useSupportLibrary=false
    和着色 不起作用

使用PNG处理所有版本:

增编:

这项技术也适用于棒棒糖后,但与棒棒糖前的其他技术一样,我得到了可绘制的颜色,但没有着色:

    Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);
解决方案的种类:

感谢您的回答,到目前为止,我能想到的给支持向量着色的唯一简单方法是在支持向量上设置一个颜色过滤器-这意味着
DrawableCompat.setTint()
函数对于我来说似乎不起作用,如果所讨论的DrawableCompat是一个支持向量。我不确定这是一个合法的错误,预期的行为,还是我只是做错了什么

以下是我目前的解决方案:

    Drawable bg;
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
        exitButton.setColorFilter(headerTitleColor, PorterDuff.Mode.MULTIPLY);
    }
    else {
        bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
        DrawableCompat.setTint(bg, headerTitleColor);
    }
    exitButton.setImageDrawable(bg);
drawingbg;
if(Build.VERSION.SDK\u INT
您可以使用ImageView的方法:


imageView.setColorFilter(headerTitleColor,android.graphics.PorterDuff.Mode.MULTIPLY)

首先,你应该使用
VectorDrawableCompat#create
,一旦你有了
DrawableCompat
,你就必须调用
DrawableCompat#wrap

潜在地包裹可拉丝,以便可用于染色 不同的API级别,通过此类中的着色方法

因此,您的代码如下所示:

ImageView iv = ....
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null);
d = DrawableCompat.wrap(d);
DrawableCompat.setTint(d, headerTitleColor);
iv.setImageDrawable(d);

Kotlin的另一个便捷解决方案:

fun Context.drawableWithColor(@DrawableRes drawableRes: Int, @ColorInt color: Int): Drawable? {
    val pic = ContextCompat.getDrawable(this, drawableRes)
    pic?.setColorFilter(color, PorterDuff.Mode.SRC_IN)
    return pic
}
使用方法非常简单:

val drawable = context.drawableWithColor(R.drawable.your_awesome_drawable, Color.BLUE)

如果您使用Vector Compat库来创建绘图,它是否有效?i、 e VectorDrawableCompat.create(getResources(),R.drawable.ic_action_add,null)我已经更新了我的答案,看起来这是做同样事情的另一种技术(!),但对预照明不起作用的着色不是另一种技术,这就是应该如何创建
VectorDrawableCompat
的方法,如果您阅读
DrawableCompat
文档,您会看到这一切正常,谢谢!我想做更多的测试,但对我来说,关键的缺失部分似乎是调用
wrap()
drawable。这似乎是pre-L所必需的,同时还需要调用
create
,而不仅仅是加载绘图表或通过视图引用它。实际上,我在wrap调用中尝试了这两种方法,但不是
create
!如果你想发布一个答案告诉我如何包装它,我会标记:)目前这似乎是最好的解决方案,尽管我对此并不满意!我曾在另一个地方使用过同样的工具,它工作正常,但这次不工作我不知道为什么imageView imageView=new imageView(new ContextThemeWrapper(parent.getContext(),R.style.CalendarCell_CalendarDate));imageView.setDuplicateParentStateEnabled(true);addView(imageView,new FrameLayout.LayoutParams(50,50,中心垂直));父.setDayOfMonthTextView(imageView);Drawable d=VectorDrawableCompat.create(getResources(),R.Drawable.ic_circle,null);d=可拉伸相容包装(d);DrawableCompat.setTint(d,dailyLim.intValue());cellView.getDayOfMonthImageView().setImageDrawable(d);什么是
dailyLim.intValue()
?对于测试,请将其替换为
Color.RED
让我试试这个
ImageView iv = ....
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null);
d = DrawableCompat.wrap(d);
DrawableCompat.setTint(d, headerTitleColor);
iv.setImageDrawable(d);
fun Context.drawableWithColor(@DrawableRes drawableRes: Int, @ColorInt color: Int): Drawable? {
    val pic = ContextCompat.getDrawable(this, drawableRes)
    pic?.setColorFilter(color, PorterDuff.Mode.SRC_IN)
    return pic
}
val drawable = context.drawableWithColor(R.drawable.your_awesome_drawable, Color.BLUE)