关于安卓着色器的使用(一)

文章介绍了在Android开发中如何使用着色器来改变图片颜色,包括在XML中通过app:tint属性设置和在代码中使用DrawableCompat动态设置。当涉及多个着色器时,需要调用Drawable的mutate()方法避免资源复用导致的问题。mutate()确保了对drawable的修改只影响当前实例,不影响其他共享同一资源的对象。
摘要由CSDN通过智能技术生成

背景:

对于着色器的使用,相信大部分的场景都有可能出现,例如以下的场景:
同一个图片,不同的颜色。这个时候,就可以使用着色器进行配置。

环境

as 4.2.2
jdk 8
win 10

使用

(一)xml中使用。当在xml中使用的时候,只需要申明即可,例子如下:

                        <ImageView
                            android:id="@+id/iv_select_music"
                            android:layout_width="12dp"
                            android:layout_height="12dp"
                            android:src="@drawable/ic_select_course_subject_arr"
                            app:layout_constraintBottom_toBottomOf="@+id/tv_select_music_text"
                            app:layout_constraintEnd_toEndOf="parent"
                            app:layout_constraintTop_toTopOf="@+id/tv_select_music_text"
                            app:tint="@color/c_line_gray" />

上述代码中, 直接设置 app:tint=“@color/c_line_gray” 既可以把图片设置成为对应的颜色。

(二)代码中设置。通过以下代码,可以动态设置着色器:

            val drawableRes = ResourcesCompat.getDrawable(
                resources,
                resId, null
            ) ?: return
            val tintIcon = DrawableCompat.wrap(drawableRes)
            DrawableCompat.setTint(tintIcon, hintColor)
            setImageDrawable(tintIcon)

注意,如果这里要处理取消着色器,重新设置setImageDrawable即可。

对于上述两种写法,页面中只有一个着色器效果的时候,都是没有问题的。若是多个着色器,则会导致复用问题。需要调用.mutate()生成一个新的drawable即可。具体实现如下:

            val drawableRes = ResourcesCompat.getDrawable(
                resources,
                resId, null
            ) ?: return
            val tintIcon = DrawableCompat.wrap(drawableRes.mutate())
            DrawableCompat.setTint(tintIcon, hintColor)
            setImageDrawable(tintIcon)

好了,观察mutate的源码解析:

    /**
     * Make this drawable mutable. This operation cannot be reversed. A mutable
     * drawable is guaranteed to not share its state with any other drawable.
     * This is especially useful when you need to modify properties of drawables
     * loaded from resources. By default, all drawables instances loaded from
     * the same resource share a common state; if you modify the state of one
     * instance, all the other instances will receive the same modification.
     *
     * Calling this method on a mutable Drawable will have no effect.
     *
     * @return This drawable.
     * @see ConstantState
     * @see #getConstantState()
     */
    public @NonNull Drawable mutate() {
        return this;
    }

大概的意思,如果不使用mutate的情况下,因为安卓共用一个同resId的drawable对象,所以如果drawable对象的属性发生了变化,则会导致其他使用到该drawable的地方,也会发生变化。若使用了该方法后,drawable对象的属性修改,不会对原有的共享的drawble对象产生影响。

that’s all-----------------------------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值