最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android使用Tint為圖標(biāo)Icon動態(tài)著色的操作方法

 更新時間:2025年11月25日 08:39:22   作者:kerli  
本文介紹了在Android中使用Tint為圖標(biāo)動態(tài)著色的方法,可以通過xml或代碼設(shè)置Tint屬性,從而實現(xiàn)單張圖片的動態(tài)著色,節(jié)省包體積,需要注意的是,同時設(shè)置ImageView與Drawable的Tint時,要關(guān)注覆蓋問題,需要的朋友可以參考下

1. 背景

在 App 當(dāng)中,會有很多 形狀相同、顏色不同 的 Icon。

例如上圖這個場景,是篩選項的 icon,對應(yīng)的代碼可能為:

  • Xml 中初始化顏色為黑色
<ImageView
    ...
    android:src="@drawable/icon_filter_black" />
  • 代碼中根據(jù)篩選狀態(tài),切換不同顏色的 icon
// XXXFragment.kt

imageView.setImageDrawable(
    if (isSelect) {
        // 篩選后為橙色
        resources.getDrawable(R.drawable.icon_filter_orange);
    } else {
        // 未篩選為黑色
        resources.getDrawable(R.drawable.icon_filter_black);
    }
)

如果為每種顏色的 Icon 都保存一張圖片,會增加包體積。同時,會增加設(shè)計的工作負(fù)擔(dān)。有沒有什么辦法可以做到只需要一張圖片,然后動態(tài)的著色呢?

2. 使用 Tint 動態(tài)著色

2.1 使用方式

有以下幾種方式:

  1. xml 中設(shè)置
<ImageView
    ...
    android:src="@drawable/icon_filter" 
    app:tint="@color/black"
    />
  1. 代碼中為 ImageView 設(shè)置
imageView.imageTintList = ColorStateList(...)
  1. 代碼中直接為 Drawable 設(shè)置
val drawable = resources.getDrawable(R.drawable.icon_filter)
drawable.setTint = Color.BLACK

imageView.setImageDrawable(drawable)

設(shè)置 tint 后,繪制時就會用 tint 的顏色渲染 icon。這樣,就算只有一張圖片,也可以渲染為多種顏色。很大程度的節(jié)省了包體積。

2.2 原理分析

  • ImageView 會將 Tint 傳給 Drawable
 // ImageView.java
public void setImageTintList(@Nullable ColorStateList tint) {
    mDrawableTintList = tint;
    mHasDrawableTint = true;
    
    applyImageTint();
}

private void applyImageTint() {
    if (mDrawable != null && (mHasDrawableTint || mHasDrawableBlendMode)) {
        mDrawable = mDrawable.mutate();
        
        if (mHasDrawableTint) {
            mDrawable.setTintList(mDrawableTintList); // 將 tint 傳遞給 Drawable!
        }
        // ...
    }
}
  • Drawable 在 收到 Tint 時會創(chuàng)建 ColorFilter,在 draw 時會用它做顏色過濾處理。這里拿 VectorDrawable 舉例:
public class VectorDrawable extends Drawable {
    private BlendModeColorFilter mBlendModeColorFilter ;
    
    @Override
    public void setTintList(ColorStateList tint) {
        // 使用 tint 創(chuàng)建 ColorFilter
        updateColorFilters(... , tint) ;
    }
    
    private void updateColorFilters(@Nullable BlendMode blendMode , ColorStateList tint) {
        // ...
    mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter , tint , blendMode) ;
    }
    
    @Override
    public void draw(Canvas canvas) {
        // 繪制時,如果外部沒有設(shè)置 mColorFilter,則使用 mBlendModeColorFilter
        final ColorFilter colorFilter = (mColorFilter == null ? mBlendModeColorFilter : mColorFilter) ;
        // ...
    }
}

public abstract class Drawable {
    @Nullable 
    BlendModeColorFilter updateBlendModeFilter(@Nullable ColorStateList tint , ... ) {
        // ... 
        final int color = tint.getColorForState(getState() , Color.TRANSPARENT) ;
    
        if (blendFilter == null || blendFilter.getColor() != color
                || blendFilter.getMode() != blendMode) {
            return new BlendModeColorFilter(color , blendMode) ;
        }
        
        return blendFilter ;
    }
}

3. 注意事項

3.1 同時設(shè)置 ImageView 與 Drawable,Drawable 的設(shè)置會失效

  • 例如,我們在 xml 中設(shè)置 tint 為黑色
<ImageView
    ...
    android:src="@drawable/icon_filter"
    app:tint="@color/black"
    />
  • 在代碼中,為 Drawable 設(shè)置為黃色
val drawable = resources.getDrawable(R.drawable.icon_filter)
drawable.setTint = Color.YELLOW

imageView.setImageDrawable(drawable)
  • 此時,對 Drawable 的設(shè)置是不生效的,因為此時 ImageView.setImageDrawable 會覆蓋掉 Drawable 自身的 tint
// ImageView.kt

public void setImageDrawable(@Nullable Drawable drawable) {
    updateDrawable(drawable) ;
}

private void updateDrawable(Drawable d) {
    applyImageTint() ;
}

private void applyImageTint() {
    if (mHasDrawableTint) {
        mDrawable.setTintList(mDrawableTintList) ;
    }
}
  • 所以如果同時設(shè)置 ImageView 與 Drawable 的 tint,要關(guān)注覆蓋問題。

到此這篇關(guān)于Android使用Tint為圖標(biāo)Icon動態(tài)著色的操作方法的文章就介紹到這了,更多相關(guān)Android Tint為Icon動態(tài)著色內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

光山县| 会宁县| 泰州市| 玉山县| 延津县| 东平县| 盈江县| 台北市| 秦皇岛市| 甘德县| 廉江市| 抚州市| 五华县| 延津县| 榆林市| 普宁市| 红桥区| 南雄市| 介休市| 饶平县| 阿瓦提县| 平远县| 桐城市| 汉寿县| 贵南县| 浦江县| 罗山县| 双鸭山市| 和硕县| 乐都县| 卢氏县| 南涧| 娱乐| 旌德县| 黄浦区| 衡南县| 剑阁县| 乾安县| 金门县| 启东市| 巴中市|