- 原文地址:Locale changes and the AndroidViewModel antipattern
- 原文做者:Jose Alcérreca
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:solerji
TL;DR:從視圖模型中公開資源 ID 以免顯示廢棄的數據。前端
在 ViewModel 中,若是要公開來自資源(字符串、可繪製文件、顏色……)的數據,則必須着重考慮 ViewModel 對象而忽視配置更改,例如區域設置更改。當用戶更改其區域設置時,活動將從新被建立,但不建立 ViewModel 對象。android
AndroidViewModel
是已知應用程序上下文的 ViewModel
的子類。然而,若是您沒有注意到或沒有對上下文的生命週期作出反應,訪問上下文多是危險的。建議的作法是避免處理在 ViewModels 中具備生命週期的對象。ios
讓咱們看看跟蹤器中基於此問題的示例:在系統區域設置更改時更新 ViewModel 。git
// 別這麼作
public class MyViewModel extends AndroidViewModel {
public final MutableLiveData<String> statusLabel = new MutableLiveData<>();
public SampleViewModel(Application context) {
super(context);
statusLabel.setValue(context.getString(R.string.labelString));
}
}
複製代碼
問題的關鍵是字符串在構造器中只解釋一次。若是有區域設置更改,則不會從新建立視圖模型。這將致使咱們的應用程序顯示廢棄的數據,所以只能部分本地化。github
正如 Sergey 在評論中指出的那樣 comments,推薦的方法是公開要加載的資源的 ID ,並在視圖中這樣作。因爲視圖(活動、片斷等)具備生命週期意識,所以它將在配置更改後從新建立,以便正確地從新加載資源。後端
// 顯示資源ID
public class MyViewModel extends ViewModel {
public final MutableLiveData<Int> statusLabel = new MutableLiveData<>();
public final MutableLiveData<Int> statusLabel = new MutableLiveData<>();
public SampleViewModel(Application context) {
super(context);
statusLabel.setValue(R.string.labelString);
}
}
複製代碼
即便你不打算本地化你的應用程序,它也會使測試變得更容易而且清空你的 ViewModel 對象,所以沒有理由不去考慮它的前瞻性。架構
咱們在以 Java 爲基礎的 Android 架構存儲庫中解決了這個問題 Java 以及在Kotlin 分支上。咱們也把資源轉移到 數據綁定佈局。佈局
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。區塊鏈
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。測試