MVVMパターンを用いてTodoアプリのサンプルアプリをKotlinで実装しました。
完成形のアプリはこんな感じです。
すべてのソースコードはこちらhttps://github.com/tokku5552/TODOAppSample-Kotlin
こちらのQiitaの記事でKotlinとFlutterで書いたバージョンを比較しています。
アーキテクチャの概要
ざっくりとしたアーキテクチャ図です。主な画面はTodo一覧(TodoListFragment)と詳細画面(TodoItemDetailFragment)です。MainActivityとMainActivityViewModelは画面遷移に関わる処理のみ行い、実際の画面描画はFragmentで行っています。
DBにはRealm2.1.1を使用しています。
MainActivityの役割
ViewModelのLiveDataであるnavigateToFragmentをobserveして変更があればViewModel側のshowFragmentメソッドで画面遷移を行います。
MainActiveViewModelには画面遷移を伴う関数を配置しておき、それをFragmentからも実行できるようにします。
Todo一覧画面
Todoを一覧表示するために、まずTodoItemというModelとリストビューにバインドするためのTodoItemAdapterを用意します。
今回はローカルDBとしてRealmを利用するので、TodoItemはRealmObjectを継承します。
アダプターはRealmRecyclerViewAdapterを継承するようにします。
内部でViewHolderを実装する必要がありますが、DataBindingでバインドするために、bindTo関数を定義し、中でexcutePendingBindingsします。
これをFragment内でバインドしてあげます。
これでDBに変更があるたびに勝手に一覧をバインドしてくれるようになります。
databind便利!
また、一覧画面内でDBに変更処理がある場合の処理はすべてViewModel側で実装し、Fragment側でリスナーにセットします。
SQLiteと違い、RealmはC#でいうLinqのような書き方でクエリを記述できます。
Todo詳細画面
一覧画面でFloatingActionButtonを押したとき、もしくはタスクのラベル部分を押したときに詳細画面に遷移します。
FAB(FloatingActionButton)ではcreateTaskが呼ばれ、一覧でタスクが押された時はtodoItemClickedが呼ばれます。
共通である戻るボタンのリスナーを先にセットした後は、selectedItemが渡ってきているかどうかで、新規作成か、更新かを判断します。
ViewModelでは新規作成と更新の処理を実装します。
その他
Realmを用いて開発を進めていく中で、「この値も保持しとかないといけなかった!」と後から気が付いて、スキーマを変更したくなる場面が出てきます。
ですが、単純にTodoItemに値を追加しても、エラーが表示されてしまいます。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: tech.tokku_engineer.todoappsample_kotlin, PID: 25942
java.lang.RuntimeException: Unable to resume activity {tech.tokku_engineer.todoappsample_kotlin/tech.tokku_engineer.todoappsample_kotlin.MainActivity}: io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
- Property 'TodoItem.isDone2' has been added.
上記のようなエラーが発生したら、スキーマを移行する必要があります。
そのために以下のようなコードを追加しました。
もし現在のバージョンが0ならば、TodoItemのスキーマからisDeleteというフィールドを削除するように実装します。
そして上記のようにアプリケーションクラスを作成し、onCreateをオーバライドして、その中でスキーマバージョンに変更があれば、マイグレーション処理を実行するようにします。
あとはこれをAndroidManifest.xml内で定義して読み込むようにしてあげればOKです。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tech.tokku_engineer.todoappsample_kotlin">
<application
android:name=".TodoAppSampleKotlinApplication"
:
:
:
</application>
</manifest>
まとめ
今回はKotlinでMVVMを用いたTodoアプリを作成してみました。
data bindingを用いてFragmentまでDBの値を持ってくる処理ですが、まぁまぁ適切に分離出来ているのではないかなと思います。
全てのコードはこちら
参考:
【Android】分かった気になれる!アーキテクチャ・MVVM概説(https://qiita.com/iTakahiro/items/6b1b22efa69e55cea3fa)
Realmと使うAndroid Architecture Components(https://academy.realm.io/jp/posts/android-architecture-components-and-realm/)
コメント
とても分かりやすいサイトで勉強がはかどります
今後も参考にさせていただきます
コメントありがとうございます!今後も価値のある記事を書けるよう頑張ります^^