はじめに
qiita.com こちらの記事をベースにMVVMについて学習したので,その備忘録です.
MVVM
フォルダ階層
.
├── service
│ ├── model
│ │ ├── Project.java
│ │ └── User.java
│ └── repository
│ ├── GithubService.java
│ └── ProjectRepository.java
├── view
│ └── ui
│ └── MainActivity.java
└── viewmodel
└── ProjectListViewModel.java
model
- UIに関係ない処理を行う場所
- repositoryはviewModelに対するデータプロバイダ(API叩くソースを書くところ)
- viewModelから呼び出され,コルーチン(非同期)でサーバからデータを取得
- [コルーチン]関数呼び出しを途中で中断できるが,スタック領域に残っており,もう一度呼ぶとその中断したところから再開できる
MVVMSamleで使ったkotlin文法
companionKotlin では、class 定義の中で object を宣言するとき、companion というキーワードをつけることができる。このキーワードがついた object をコンパニオンオブジェクトと呼ぶ.コンパニオンオブジェクトのメンバは クラス名.メンバ名 でアクセスできる.- つまりjavaのstaticの代わり
- companion object の後ろの {} の中は、通常のクラスの本体と同じように実装
companion object Factoryのように名前付けられるけど,Book.Factory.FREE_PRICEでもBook.FREE_PRICEでもどっちでもアクセス可能- しかも,クラスの中でcompanion objectは1つしかだめだから,名前つける意味ないかもね
companion補足
data class Book(val title: String, val price: Int) { companion object { const val FREE_PRICE = 0 fun newFreeBook(title: String) = Book(title, FREE_PRICE) } } fun main() { val book = Book.newFreeBook("Free Kotlin") println(book) //=> Book(title=Free Kotlin, price=0) }
- Book.xxx() という記述は、実は Book.Companion.xxx() の省略記法 https://qiita.com/satorufujiwara/items/f42b176404287690f1d0
MutableLiveData vs ObservableFiel
両方ともDataBindingに使えるオブジェクト
MutableLiveData<>()- ActivityやFragmentのライフサイクルに応じて、ほぼ自動で購読管理をしてくれる。
- 意図しないクラッシュ防ぐことができる
- DataBindingできる
ObservableField<>()- DataBindingをするときに使う。
- ライフサイクルには対応しておらず、購読管理を自動ですることはできない
MutableLiveDataを使いましょう
Application
- viewModelからリソースにアクセスしたりできる
- viewModelProvidersで初期化するにはViewModelかAndroidViewModelを継承する必要がある
- この方法で初期化したViewModelは画面回転時も値を引き継ぐことができる
- ViewModelProviders.of()で渡すものによってViewModelのスコープが決定
- Activityを渡せばそのActivityで使えますし、Fragmentと同じ
- Fragmentで親Activityのインスタンスを渡せばActivity内のスコープとなるため、ActivityとFragmentで同じViewModelを操作することができる
- コールバック付けなくても,データ共有できるみたい
class ProjectViewModel(private val myApplication: Application, private val mProjectID: String) : AndroidViewModel(myApplication)
