【移動應用開發(fā)技術】Android著色器Tint怎么使用_第1頁
【移動應用開發(fā)技術】Android著色器Tint怎么使用_第2頁
【移動應用開發(fā)技術】Android著色器Tint怎么使用_第3頁
【移動應用開發(fā)技術】Android著色器Tint怎么使用_第4頁
【移動應用開發(fā)技術】Android著色器Tint怎么使用_第5頁
免費預覽已結束,剩余2頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

【移動應用開發(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論