日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Android著色器Tint研究

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

創(chuàng)新互聯(lián)主營丹陽網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都app開發(fā),丹陽h5微信小程序開發(fā)搭建,丹陽網(wǎng)站營銷推廣歡迎丹陽等地區(qū)企業(yè)咨詢

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

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

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

下面就來簡單說一下,tint的使用 以及需要注意的地方。

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

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

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

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

 應(yīng)該很好理解對吧,代碼就不解釋了。但是我們運行以后發(fā)現(xiàn): 

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

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

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

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

解決方法 其實也很簡單:

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

修改以后 我們再看: 

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

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

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

大部分的內(nèi)存還是公用的!

然后接著來,我們看下一個例子 關(guān)于editext的。 

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

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

  

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

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

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

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

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

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

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

并且我們要看下editor的源碼 這是和edittext息息相關(guān)的:

 
 
 
 
  1. /** 
  2.      * EditText specific data, created on demand when one of the Editor fields is used. 
  3.      * See {@link #createEditorIfNeeded()}. 
  4.      */ 
  5.     private Editor mEditor; 
  6.  
  7.  
  8. //注意這段代碼屬于editor   
  9. final Drawable[] mCursorDrawable = new Drawable[2];  

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

 
 
 
 
  1. //參數(shù)就是要反射修改光標的edittext對象 
  2.     private void invokeEditTextCallCursorDrawable(EditText et) { 
  3.         try { 
  4.             Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); 
  5.             // 看源碼知道 這個變量不是public的 所以要設(shè)置下這個可訪問屬性 
  6.             fCursorDrawableRes.setAccessible(true); 
  7.             //取得 editext對象里的mCursorDrawableRes 屬性的值 看源碼知道這是一個int值 
  8.             int mCursorDrawableRes = fCursorDrawableRes.getInt(et); 
  9.             //下面的代碼 是通過獲取mEditor對象 然后再通過拿到的mEditor對象來獲取最終我們的mCursorDrawable這個光標的drawable 
  10.             Field fEditor = TextView.class.getDeclaredField("mEditor"); 
  11.             fEditor.setAccessible(true); 
  12.             Object editor = fEditor.get(et); 
  13.             Class clazz = editor.getClass(); 
  14.             Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); 
  15.             fCursorDrawable.setAccessible(true); 
  16.             if (mCursorDrawableRes <= 0) { 
  17.                 return; 
  18.             } 
  19.             //到這里 我們終于拿到了默認主題下 edittext的光標的那個小圖標的drawable 
  20.             Drawable cursorDrawable = et.getContext().getResources().getDrawable(mCursorDrawableRes); 
  21.             if (cursorDrawable == null) { 
  22.                 return; 
  23.             } 
  24.             //既然都拿到了這個drawble 那就修改他。 
  25.             Drawable tintDrawable = tintDrawable(cursorDrawable, ColorStateList.valueOf(Color.GREEN)); 
  26.             //前面貼出的mCursorDrawable源碼 可以知道 這是一個二維數(shù)組。所以我們要構(gòu)造出一個全新的二維數(shù)組 
  27.             Drawable[] drawables = new Drawable[]{tintDrawable, tintDrawable}; 
  28.             //然后再通過反射 把這個二維數(shù)組的值 放到editor里面 即可! 
  29.             fCursorDrawable.set(editor, drawables); 
  30.         } catch (NoSuchFieldException e) { 
  31.             e.printStackTrace(); 
  32.         } catch (IllegalAccessException e) { 
  33.             e.printStackTrace(); 
  34.         } 
  35.   
  36.     }  

***調(diào)用這個方法以后看一下效果:

很*** 對吧~~

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

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

當然你也可以用http://andraskindler.com/blog/2015/tinting_drawables/ 這個文章里的方法來做向下兼容:public final class TintedBitmapDrawable extends BitmapDrawable { 

 
 
 
 
  1.   private int tint; 
  2.   private int alpha; 
  3.   
  4.   public TintedBitmapDrawable(final Resources res, final Bitmap bitmap, final int tint) { 
  5.     super(res, bitmap); 
  6.     this.tint = tint; 
  7.     this.alpha = Color.alpha(tint); 
  8.   } 
  9.   
  10.   public TintedBitmapDrawable(final Resources res, final int resId, final int tint) { 
  11.     super(res, BitmapFactory.decodeResource(res, resId)); 
  12.     this.tint = tint; 
  13.     this.alpha = Color.alpha(tint); 
  14.   } 
  15.   
  16.   public void setTint(final int tint) { 
  17.     this.tint = tint; 
  18.     this.alpha = Color.alpha(tint); 
  19.   } 
  20.   
  21.   @Override public void draw(final Canvas canvas) { 
  22.     final Paint paint = getPaint(); 
  23.     if (paint.getColorFilter() == null) { 
  24.       paint.setColorFilter(new LightingColorFilter(tint, 0)); 
  25.       paint.setAlpha(alpha); 
  26.     } 
  27.     super.draw(canvas); 
  28.   } 
  29. }  

當前名稱:Android著色器Tint研究
鏈接URL:http://www.5511xx.com/article/cdpodej.html