下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發(fā)技術】Android著色器Tint怎么使用
本篇內容介紹了“Android著色器Tint怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓在下帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!Tint這個東西主要用來減少apk體積的,比如說我現(xiàn)在有一個textview,他的背景圖有兩種,一種是當獲得焦點時顯示的a圖,另一種是
失去焦點時顯示的b圖。相信大家開發(fā)的時候這種需求做過很多次了,我們一般都會發(fā)現(xiàn)這種a圖和b圖
除了顏色不一樣,其他都是一樣的,但是我們做的時候呢,通常是找ui要了兩張圖。如果要適配分辨率的話很有可能圖片會更多,而且在切換的時候因為是重新加載一次bitmap效率也會下降很多。所以谷歌就給了一套解決方案
這個就是tint了。他的目的就是當你發(fā)現(xiàn)有這種需求的時候,只需要放一張圖在apk里即可,當你需要改變背景圖的顏色的時候就用Tint即可!首先我們定義一個簡單的布局文件:我們發(fā)現(xiàn)這2個imageview都是引用的同樣一個drawable資源,并且在studio這個xml編輯界面里面我們很明顯的能看出來
這個圖片的顏色是黑色的對吧!那現(xiàn)在我們想改一下,想把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)));應該很好理解對吧,代碼就不解釋了。但是我們運行以后發(fā)現(xiàn):臥槽怎么2個都變綠色了!回顧一下我們的代碼我們應該能明白2個imageview都是引用的同樣的一個drawable,要知道
既然是一個drawable,那系統(tǒng)肯定為了優(yōu)化資源把這2個drawable在內存里的拷貝弄成了一份!還記得我們以前講的bitmap優(yōu)化那篇么?/punkisnotdead/p/4881771.html
和這個里面的inBitmap屬性有異曲同工之妙,如果還不理解你看下面的圖就理解了:所以才會造成上面的情況。你修改了共同變量,所以2個圖就都被影響了。解決方法其實也很簡單:final
Drawable
originBitmapDrawable
=
getResources().getDrawable(R.drawable.
ic_account_circle_black_18dp).mutate();修改以后我們再看:你看這么做就一切正常了。那有人就要問了,臥槽你這么做
不是把谷歌給我們做好的圖片內存優(yōu)化方案給損壞了么,其實這種擔心是多余的,這個http://android-developers.blogspot.hk/2009/05/drawable-mutations.html這個地址會告訴你其實我們做只是把單獨的受到影響的那部分內存給單獨拿出來了,其他沒受到影響的還是共享的數(shù)據(jù)!換句話說我們內存里
會另外存放的就是一些純的標志位之類的類似于狀態(tài)值這種東西。大部分的內存還是公用的!然后接著來,我們看下一個例子關于editext的。你看這個edittext的顏色是這樣的。那現(xiàn)在我們來修改一下這個edittext的背景色et1
=
(EditText)
this.findViewById(R.id.et);
final
Drawable
originBitmapDrawable
=
et1.getBackground();
et1.setBackgroundDrawable(tintDrawable(originBitmapDrawable,
ColorStateList.valueOf(Color.GREEN)));背景色是修改成功了但是這個光標的顏色還沒變非常不協(xié)調,有人又要說了我們可以用:這個xml屬性來修改呀,當然了這個方法確實是可以的但是你想你這么做的話又要增加資源文件了,不是與我們的tint背道而馳了么?所以這個地方我們就要想辦法突破一下。其實很多人都能想到方法了,對于android沒有提供給我們的api比如那些private函數(shù),我們通常都是通過反射的方法去調用的。這里也是一樣,稍微想一下我們就能明白,這個地方
我們就先通過反射來獲取到這個cursorDrawable然后給他著色,然后在反射調用方法給他set進去不就行了么?首先我們都知道editext實際上就是textview,所以我們看一下textview的源碼找找看這個屬性到底叫啥名字。經過一番努力發(fā)現(xiàn)
在這://
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="/members/57845349">@link</a>
#createEditorIfNeeded()}.
*/
private
Editor
mEditor;
//注意這段代碼屬于editor
final
Drawable[]
mCursorDrawable
=
new
Drawable[2];有了這段代碼我們就知道剩下反射的代碼怎么寫了。//參數(shù)就是要反射修改光標的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源碼
可以知道
這是一個二維數(shù)組。所以我們要構造出一個全新的二維數(shù)組
Drawable[]
drawables
=
new
Drawable[]{tintDrawable,
tintDrawable};
//然后再通過反射
把這個二維數(shù)組的值
放到editor里面
即可!
fCursorDrawable.set(editor,
drawables);
}
catch
(NoSuchFieldException
e)
{
e.printStackTrace();
}
catch
(IllegalAccessException
e)
{
e.printStackTrace();
}
}***調用這個方法以后看一下效果:***tintDrawable這個方法是用來向下兼容用的。你如果不考慮向下兼容的問題用系統(tǒng)自帶的方法就可以了,這里就不做過多介紹了。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
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年代理加盟協(xié)議范本
- 《民族復興中國夢》課件
- 2025年個人消費貸款抵押合同
- 2025年化學災難責任保險合同
- 2025年寬帶網絡使用協(xié)約
- 2025年石材質押合同
- 2025版綠色建筑項目募集資金三方監(jiān)管與支持合同4篇
- 2025版信息安全管理體系委托管理合同范本3篇
- 2025版衛(wèi)生間裝修材料環(huán)保認證協(xié)議書3篇
- 2025版農業(yè)設施設計顧問服務協(xié)議3篇
- 醫(yī)院三基考核試題(康復理療科)
- 2024-2030年中國招標代理行業(yè)深度分析及發(fā)展前景與發(fā)展戰(zhàn)略研究報告
- 醫(yī)師定期考核 (公共衛(wèi)生)試題庫500題(含答案)
- 基因突變和基因重組(第1課時)高一下學期生物人教版(2019)必修2
- 內科學(醫(yī)學高級):風濕性疾病試題及答案(強化練習)
- 音樂劇好看智慧樹知到期末考試答案2024年
- 辦公設備(電腦、一體機、投影機等)采購 投標方案(技術方案)
- 案卷評查培訓課件模板
- 2024年江蘇省樣卷五年級數(shù)學上冊期末試卷及答案
- 人教版初中英語七八九全部單詞(打印版)
- 波浪理論要點圖解完美版
評論
0/150
提交評論