91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android著色器Tint怎么使用

發布時間:2021-12-18 16:25:42 來源:億速云 閱讀:122 作者:iii 欄目:移動開發

本篇內容介紹了“Android著色器Tint怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Tint 這個東西 主要用來減少apk體積的,比如說我現在有一個textview,他的背景圖 有兩種,一種是當獲得焦點時顯示的a圖,另一種是  失去焦點時顯示的b圖。

相信大家開發的時候 這種需求做過很多次了,我們一般都會發現 這種a圖和b圖  除了顏色不一樣,其他都是一樣的,但是我們做的時候呢,通常是找ui要了兩張圖。

如果要適配分辨率的話 很有可能圖片會更多,而且在切換的時候 因為是重新加載一次bitmap 效率也會下降很多。所以谷歌就給了一套解決方案  這個就是tint了。

他的目的就是當你發現有這種需求的時候,只需要 放一張圖 在apk里即可,當你需要改變背景圖的顏色的時候 就用Tint即可!

首先 我們定義一個簡單的布局文件:

Android著色器Tint怎么使用

我們發現這2個imageview 都是引用的同樣一個drawable資源,并且 在studio這個xml編輯界面里面 我們很明顯的 能看出來  這個圖片的顏色是黑色的 對吧!

那 現在 我們想改一下,想把iv1 這個imageview的 背景色 改成綠色的! 我們想當然的 當然會這么寫:

iv1 = (ImageView) this.findViewById(R.id.iv1);   iv2 = (ImageView) this.findViewById(R.id.iv2);   final Drawable originBitmapDrawable = getResources().getDrawable(R.drawable.ic_account_circle_black_18dp);   iv1.setImageDrawable(tintDrawable(originBitmapDrawable, ColorStateList.valueOf(Color.GREEN)));

應該很好理解對吧,代碼就不解釋了。但是我們運行以后發現:

Android著色器Tint怎么使用

臥槽 怎么2個都變綠色了!

回顧一下 我們的代碼 我們應該能明白 2個imageview 都是引用的同樣的一個drawable,要知道  既然是一個drawable,那系統肯定為了優化資源 把這2個drawable 在內存里的拷貝弄成了一份!

還記得 我們以前講的bitmap優化那篇么?http://www.cnblogs.com/punkisnotdead/p/4881771.html  和這個里面的inBitmap 屬性有異曲同工之妙,如果還不理解 你看下面的圖就理解了:

Android著色器Tint怎么使用

所以才會造成上面的情況。你修改了共同變量,所以2個圖就都被影響了。

解決方法 其實也很簡單:

final Drawable originBitmapDrawable = getResources().getDrawable(R.drawable. ic_account_circle_black_18dp).mutate();

修改以后 我們再看:

Android著色器Tint怎么使用

你看這么做就一切正常了。

那有人就要問了,臥槽 你這么做  不是把谷歌給我們做好的圖片內存優化方案給損壞了么,其實這種擔心是多余的,這個http://android-developers.blogspot.hk/2009/05/drawable-mutations.html

這個地址會告訴你 其實我們做 只是把單獨的受到影響的那部分 內存給單獨拿出來了,其他沒受到影響的還是共享的數據!換句話說 我們內存里  會另外存放的就是一些純的標志位 之類的 類似于狀態值這種東西。

大部分的內存還是公用的!

然后接著來,我們看下一個例子 關于editext的。

Android著色器Tint怎么使用

你看這個edittext 的顏色是這樣的。那現在我們來修改一下 這個edittext的背景色

et1 = (EditText) this.findViewById(R.id.et);   final Drawable originBitmapDrawable = et1.getBackground();   et1.setBackgroundDrawable(tintDrawable(originBitmapDrawable, ColorStateList.valueOf(Color.GREEN)));

Android著色器Tint怎么使用

背景色是修改成功了 但是這個光標的顏色 還沒變 非常不協調, 有人又要說了 我們可以用:

Android著色器Tint怎么使用

這個xml 屬性來修改呀,當然了這個方法確實是可以的 但是你想 你這么做的話 又要增加資源文件了,不是與我們的tint 背道而馳了么?

所以 這個地方 我們就要想辦法 突破一下。其實很多人都能想到方法了,對于android 沒有 提供給我們的api 比如那些private 函數,

我們通常都是通過反射的方法 去調用的。 這里也是一樣,稍微想一下 我們就能明白, 這個地方  我們就先通過反射來獲取到這個cursorDrawable

然后給他著色,然后在反射調用方法 給他set進去不就行了么?

首先我們都知道 editext 實際上就是textview,所以我們看一下textview 的源碼 找找看 這個屬性到底叫啥名字。經過一番努力發現  在這:

// Although these fields are specific to editable text, they are not added to Editor because   // they are defined by the TextView's style and are theme-dependent.   int mCursorDrawableRes;

并且我們要看下editor的源碼 這是和edittext息息相關的:

/**      * EditText specific data, created on demand when one of the Editor fields is used.      * See {<a href="http://www.jobbole.com/members/57845349">@link</a> #createEditorIfNeeded()}.      */     private Editor mEditor;   //注意這段代碼屬于editor   final Drawable[] mCursorDrawable = new Drawable[2];

有了這段代碼 我們就知道 剩下反射的代碼怎么寫了。

//參數就是要反射修改光標的edittext對象     private void invokeEditTextCallCursorDrawable(EditText et) {         try {             Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");             // 看源碼知道 這個變量不是public的 所以要設置下這個可訪問屬性             fCursorDrawableRes.setAccessible(true);             //取得 editext對象里的mCursorDrawableRes 屬性的值 看源碼知道這是一個int值             int mCursorDrawableRes = fCursorDrawableRes.getInt(et);             //下面的代碼 是通過獲取mEditor對象 然后再通過拿到的mEditor對象來獲取最終我們的mCursorDrawable這個光標的drawable             Field fEditor = TextView.class.getDeclaredField("mEditor");             fEditor.setAccessible(true);             Object editor = fEditor.get(et);             Class<?> clazz = editor.getClass();             Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");             fCursorDrawable.setAccessible(true);             if (mCursorDrawableRes <= 0) {                 return;             }             //到這里 我們終于拿到了默認主題下 edittext的光標的那個小圖標的drawable             Drawable cursorDrawable = et.getContext().getResources().getDrawable(mCursorDrawableRes);             if (cursorDrawable == null) {                 return;             }             //既然都拿到了這個drawble 那就修改他。             Drawable tintDrawable = tintDrawable(cursorDrawable, ColorStateList.valueOf(Color.GREEN));             //前面貼出的mCursorDrawable源碼 可以知道 這是一個二維數組。所以我們要構造出一個全新的二維數組             Drawable[] drawables = new Drawable[]{tintDrawable, tintDrawable};             //然后再通過反射 把這個二維數組的值 放到editor里面 即可!             fCursorDrawable.set(editor, drawables);         } catch (NoSuchFieldException e) {             e.printStackTrace();         } catch (IllegalAccessException e) {             e.printStackTrace();         }       }

***調用這個方法以后看一下效果:

Android著色器Tint怎么使用

***tintDrawable這個方法是用來向下兼容用的。你如果不考慮向下兼容的問題 用系統自帶的方法 就可以了,這里就不做過多介紹了。

public static Drawable tintDrawable(Drawable drawable, ColorStateList colors) {         final Drawable wrappedDrawable = DrawableCompat.wrap(drawable);         DrawableCompat.setTintList(wrappedDrawable, colors);         return wrappedDrawable;     }

當然你也可以用以下方法來做向下兼容: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);   } }

“Android著色器Tint怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洞口县| 文昌市| 彭泽县| 兰考县| 洪江市| 龙海市| 滨海县| 台东市| 贵定县| 象山县| 达日县| 新宁县| 山西省| 合江县| 娱乐| 龙南县| 绥阳县| 开化县| 邢台县| 邵阳市| 得荣县| 新河县| 永年县| 灵璧县| 赣榆县| 宁乡县| 涪陵区| 翁源县| 寿光市| 湘乡市| 九江市| 舒兰市| 厦门市| 平舆县| 肇州县| 新民市| 宁夏| 九江市| 和顺县| 绥德县| 栾川县|