一篇關於如何爲drawable和bitmap着色以匹配當前主題的短文。html
在設計Ready主題部分的時候,咱們想到了一個不只能夠改變app基本色彩,還能夠改變圖標和drawable色彩的方法。若是使用一般的作法,意味着爲每一種顏色建立一個png,而後基於選擇的主題在它們之間切換 - 代碼冗長,還增長了apk的大小。咱們還想在從此可以輕易的增長顏色,而不須要每次都建立新的資源文件。android
谷歌在v4 support library中引入了DrawableCompat 類,讓Lollipop之前的設備有了着色的功能。它的api很全,甚至支持列表的着色與RTL(右到左)佈局的倒影,可是對咱們的用例來講有點重量級了,並且你還必須把當前的Drawable用wrap()包裹。canvas
因此咱們想到了本身的解決辦法,一個輕量級的BitmapDrawable子類:TintedBitmapDrawable,它重寫了draw() 方法,實用aLightingColorFilter來處理着色的問題。它只包含三個函數,所以不用擔憂會增長太多方法個數。顏色能夠在額外增長的兩個構造函數中指定,也能夠經過setTint()方法。api
public final class TintedBitmapDrawable extends BitmapDrawable { private int tint; private int alpha; public TintedBitmapDrawable(final Resources res, final Bitmap bitmap, final int tint) { super(res, bitmap); this.tint = tint; this.alpha = Color.alpha(tint); } public TintedBitmapDrawable(final Resources res, final int resId, final int tint) { super(res, BitmapFactory.decodeResource(res, resId)); this.tint = tint; this.alpha = Color.alpha(tint); } public void setTint(final int tint) { this.tint = tint; this.alpha = Color.alpha(tint); } @Override public void draw(final Canvas canvas) { final Paint paint = getPaint(); if (paint.getColorFilter() == null) { paint.setColorFilter(new LightingColorFilter(tint, 0)); paint.setAlpha(alpha); } super.draw(canvas); } }
如何使用:緩存
tintedDrawable = new TintedBitmapDrawable(resources, R.drawable.ic_arrow_back_white_24dp, Color.GREEN);
優勢和提示app
對白色和透明圖片有效。ide
須要支持多個主題的時候,無需爲同一圖標準備多個drawable,減少了apk佔用的空間。函數
與谷歌的material圖標集完美搭配,只需下載白的的 .png 而後相應着色。佈局
也完美適用於 Palette library.this
若是和list的item使用,請緩存drawable.
若是是代碼編寫的而不是使用menu.xml,也一樣可使用在ToolBar上. 。
能夠用它來建立一個StateListDrawable,不一樣狀態下使用同一圖標作到不一樣顏色,從而減少apk體積。