国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中使用背景色Alpha值遇到的一個坑

2019-10-22 18:20:30
字體:
來源:轉載
供稿:網友

前言

Android通過設置Alpha值圖片淡化、透明度大家應該都知道,下面是段簡單的示例代碼:

View v = findViewById(R.id.img_layout); v.getBackground().setAlpha(77);// 設置背景圖片透明度;0~255透明度值 

以上是個簡單的介紹,但本文介紹的是公司項目一個留了很久的 bug,嘗試找了很多次原因都沒有頭緒。

這個 bug 是這樣的:

定義了一個主題色為例如 #FF0000,很多界面控件都用了這個顏色。可是這個顏色在 app 使用過程中用著用著就會出現變成了透明的情況,而且出現透明之后,所有使用這個顏色的控件都會變成透明。

更奇怪的是,重啟應用會恢復這個問題,但是操作一會兒又會出現。

項目有個隨著頁面滾動標題欄從透明過渡到主題色的界面實現,類似于 Design 庫中 AppBar 的那種效果。實現方法是這樣的:

// 滾動監聽器 偽代碼someParams -> { //... view.getBackground().setAlpha(percent); //...}

今天「代碼級復用」這一 feature 時,發現把 bug 也引入了新項目,才發現這個實現的問題之所在……

首先,view.getBackground() 獲得的是一個 ColorDrawable,然后給這個 ColorDrawable 設置 Alpha 值的話,會影響所有設置 background 為這個顏色的背景色的 Alpha 值。

然后就寫了個小 demo 驗證了一下這個說法,雖然不是立即生效的,然后返回退出應用后,兩個相同顏色背景的 view,改變其中一個確實會影響到另一個。

當時反應就是:WTF?難不成全局的相同顏色的 Drawable 都是同一個對象?不過很快打印了一下 background 的 drawable 對象驗證了并不是這樣——雖然這些 view 獲得的 ColorDrawable 的 Alpha 值都相同,但 hashcode 都是不同的。

所以我更傾向于這是 Android 內存優化帶來的 bug,即使這個顏色在定義時就有 Alpha 值,在修改后也會被忽略,并影響到其他的 view。該問題只在布局文件里設置 background 為一個 color 的 id 或者值,或者 setBackgroundResource 為一個 color 時存在。如果使用 new ColorDrawable(int) 來構造一個使用相同顏色值的對象則不受影響,我目前也正是使用這個方法來躲避掉這個 feature。

UPDATE:

發現文檔里有這個方法,驗證了之前的說法,從同一資源加載的 drawable 確實會共享狀態,不過有一個 mutate 方法來禁用這一特性。文檔如下:

Drawable mutate ()

Make this drawable mutable. This operation cannot be reversed. A mutable drawable is guaranteed to not share its state with any other drawable. This is especially useful when you need to modify properties of drawables loaded from resources. By default, all drawables instances loaded from the same resource share a common state; if you modify the state of one instance, all the other instances will receive the same modification. Calling this method on a mutable Drawable will have no effect.

翻譯:

Drawable mutate ()

讓一個 Drawable 變為 mutable 的。這個操作是不可逆的。一個 mutable 的 drawable 可以保證不會分享自己的狀態給其他 drawable。當一個 drawable 是從 resource 加載的,在需要更改它狀態時這個方法特別有用。在默認情況下,所有從相同 resource 的 drawable 的實例是共享一個通用狀態的;如果你修改了其中一個的狀態,所有其他的實例也會收到相同的改動。在一個已經是可變的 drawable 上調用該方法沒有效果。

所以,上述代碼只要在 drawable 獲取之后,調用一下 mutate() 方法即可。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 樟树市| 迁西县| 衡南县| 射阳县| 中卫市| 顺义区| 阜新市| 屯门区| 卢氏县| 兴和县| 岳阳市| 九江县| 微山县| 惠安县| 即墨市| 漳平市| 齐齐哈尔市| 彰化县| 普洱| 白朗县| 岗巴县| 西青区| 大渡口区| 固始县| 汽车| 张家港市| 石阡县| 广河县| 呼玛县| 越西县| 维西| 那曲县| 区。| 信阳市| 岢岚县| 定日县| 乌鲁木齐市| 将乐县| 六枝特区| 吉首市| 合川市|