
更好地支援重構
在 ide 裡使用重構的方式修改函數名稱之後,xml 中會同步進行更新。
更好用的報錯資訊
資料綁定出錯的資訊可能一下子跳出來 1,000 條,這種尴尬将成為過去。現在在建構輸出資訊視窗中,資料綁定錯誤單獨成組,這樣開發者能更輕松地找到自己需要處理的錯誤資訊。
有沒有更好的視圖通路方式?
視圖通路方法當然不止一種,但正如上圖所示的,在簡明、編譯安全和編譯速度上,各個方法總有取舍。那有沒有一種方法能一石 "三" 鳥呢?
即将到來!視圖綁定 (view binding)
給出 id 即可自動生成綁定類代碼且能保證編譯安全,能做到一石 "三" 鳥的視圖綁定可在 android studio 3.6 canary 11 或更新版本中用得上。
<!-- profile.xml -->
<linearlayout>
<textview android:id="@id/title"/>
<imageview android:id="@id/photo"/>
</linearlayout>
class profileactivity:appcompatactivity {
override fun oncreate(savedinstancestate:bundle?) {
val binding = profilebinding.inflate(layoutinflater)
setcontentview(binding.root)
// binding.title:textview
// binding.photo:imageview
}
△ 在生成的綁定類 inflate 之後,即可運作 setcontentview,如果綁定的某個類型的控件不存在則無法編譯。是時候告别 findviewbyid 了
所有的這些綁定類均由 gradle 插件生成,如果開發者修改了某個布局檔案,會報錯的也會隻有這個檔案,100% 編譯安全。
"viewmodel 和 savedstate 一樣嗎?viewmodel 會破壞 savedstate 嗎?" ——很多開發者會這麼問
基本上,開發者會通過 viewmodel 或着 savedstate 來儲存自己的内容/狀态,當應用配置發生變化時再從 viewmodel 或者 savedstate 中取回儲存的内容/狀态:
如果隻這樣粗略地了解的話,viewmodel 和 savedstate 其實是一回事。然而并不是這樣的。
savedstate 會經由 system server (一個獨立的程序) 儲存内容 (序列化的資料),也就是說,它會無視程序的限制。
而 viewmodel 則一直運作于程序内,即便應用配置發生變化,隻要程序還在,viewmodel 儲存的内容就不會消失。但隻要程序消失,viewmodel 裡的内容也會消失。
viewmodel 用于:
保留應用對網絡、資料庫的請求
當作大型對象的緩存
savedstate 用于:
ui 的狀态記錄,比如選擇區域和滾動距離等
導航狀态鍵值記錄
各取所長,聯手打造流暢體驗
// savedstatehandle
class userviewmodel(val handle: sa
vedstatehandle) : viewmodel() {
現在使用者的 viewmodel 會在構造函數中接收一個 savedstatehandle,這樣開發者就能在 viewmodel 中馬上通路 savedstate。
而這個 savedstatehandle 内部的邏輯也非常直白: 一個 map 類的鍵值結構。當然,也提供了 livedata 供通路,隻不過在這裡使用的是 mutablelivedata (因為 savedstate 是可變的)。
// map-like object
val handle : savedstatehandle
// read
val myvalue : int = handle.get("key")
// write
handle.put("key", newvalue)
// or
val livedata : mutablelivedata<int> = handle.getlivedata("key")
// observe as usual
livedata.observe (lifecycleowner) { value -> }
livedata.value = newvalue
更 kotlin 友好的代碼
我們會持續確定 kotlin 語言的首選開發語言地位。其中一個例子就是 livedata.observe 現在支援 lambda 表達式:
// lifecycle-livedata-ktx
livedata.observe(lifecycleowner) { newvalue ->
另一個例子則是 livedata 不再需要使用靜态的 transformations.map 方法:
// 以前