iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
Mobile Development

打造一個厲害的普通 Android App - 使用者體驗優化系列 第 12

使用 res 的正確姿勢 (3):番外篇

  • 分享至 

  • xImage
  •  

嗨大家今天過得好嗎?前面兩天講了 res 下的類別還可以細分成子類別、還有多語系的設定,今天想來聊聊看似簡單的 res 還可以延伸哪些用法還有踩過的坑。

動態的顏色

前面分享過 dark theme 的前置作業是要把專案中的色碼統一集合在 res/values/colors.xml 的檔案中管理,但是不是所有專案中的顏色都只能寫在同一個的檔案裡呢?其實 res/values/ 是代表預設的資料夾,使用資源時是透過種類 ( 定義每個 res 前要用 tag 代表種類,例如 <string ) 和 id 比對 res 資料夾下的每個資源,因此無論色碼、layout 或是其他資源都可以在 res 資料夾下的其他路徑、其他檔案管理和使用的。

有時候單色的元件看起來比較無聊,我們可能會希望在按鈕被點擊時改變顏色,或是標籤被選取時改變顏色,有沒有辦法用同一個 color id 就能切換不同狀態下的顏色呢?我們可以在 res/color/ 的路徑下新增一個 color 的 xml 檔案 ( 例如: _register_button_color.xml ) 再搭配 state 相關的屬性例如 state_enabled 設定 View 被啟動的顏色、 state_pressed 設定 View 被按壓的顏色,在 View 的 layout 中設定背景顏色為 _register_button_color.xml,就可以達到 View 的狀態改變時切換顏色的效果,不用在處理 VIew 的狀態改變時還要額外處理顏色。

雖然一邊讚嘆 state 的屬性真的出神入化把不同狀態的顏色一把抓管理,但使用時還有發出踩坑的驚呼,這種靜態在 xml 設定 state 的顏色或是 drawable,只有靜態寫在 layout 的 xml 才能作用,動態在 MainActivity 設定卻不會跟著 View 的狀態改變,只會載入預設的顏色不會照著屬性設定的色碼改變。這邊還沒有想通為什麼動態設定會失敗,如果有知道的邦友歡迎留言分享!

沿用重複的 view

專案中可能會有重複用到的 layout,如果每個頁面都要重複建一次就很麻煩外,之後 layout 改了就要進入使用到的每個頁面重複改,改到心累了嗎?可以使用 include 的方式把相同的 view 放入不同 layout 中使用。include 的功能是方便管理重複的 View,通常會與 mergeViewStub 一起討論,merge 可以讓 View 讓 View 的 hirerachy 變得簡單、階層更少以加快 layout 繪製的速度和提高效能;ViewStub 在 startup time 的文章討論可以讓 View 等需要時才繪製、也是加快 layout 的繪製速度。

今天主要分享使用 include 時踩到的坑,專案中想要在 include 的 layout 裡動態 addView,但為什麼 include View 裡的子 View 會拿到 NPE?因為 include 會把 included View 的 hierarchy 都擦除了,外部只拿得到 include id 但並不知道被 include View 內部裝了什麼?

解決方式有兩個一個是移除 include 設定的 id 後就拿得到內部的 view id,另一個方式是要讓外部知道 include View 的類別是哪種 View,之後就可以用 findViewById 的方式找到底下的子 View。

// 原來的 layout
<include layout="@layout/toolbar_layout" android:id="@+id/toolbar_layout" />
  • 方法一:移除 include 中的 id

    <include layout="@layout/toolbar_layout" />
    
  • 方法二:對 include 的 View 做 type cast

    val toolbarLayout = view.findViewById<RelativeLayout>(R.id.toolbar_layout)
    val toolbar: Toolbar = toolbarLayout.findViewById<Toolbar>(R.id.toolbar)
    

    使用方法二時原先使用 Kotlin Android Extensions 的方式直接去 bind view,但拿到的 toolbar 卻都是空值要改用 findViewById 才解決,但看上方的 View 是都有 import 的,不確定是不是 Extension library 的問題,有知道原因的邦友也歡迎留言解答!

以上大概是跟 res 相關我覺得蠻好用的功能和踩過的一些坑,踩坑後留下一些問題也許目前還沒有想法,希望提出來能拋磚引玉,歡迎大家提供不錯的功能或是針對問題提供一些想法,喜歡今天分享的內容的邦友請繼續關注「打造一個厲害的普通 Android App - 使用者體驗優化」的主題,我們明天見。


上一篇
使用 res 的正確姿勢 (2):多語系
下一篇
Skelton(1):Shimmer
系列文
打造一個厲害的普通 Android App - 使用者體驗優化16
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言