KotlinでRealmとRecyclerViewを使ってプロジェクトを作っていく上でいちいち調べなくてもいいようにするためのメモです。
記載しているバージョンについては適宜調整をお願いします。
ついでにこれからKotlin + Realmで導入を考えている方の助けになれば幸いです。
##開発環境
・MacBook Pro 2017
・Android Studio v3.1.3
・Kotlin v1.2.60
##KotlinでdataBindingを使えるように設定
appディレクトリ直下のbuild.gradleに以下を追加します。
apply plugin: 'kotlin-kapt'
dataBinding {
enabled = true
}
##RecyclerViewを使えるように設定
appディレクトリ直下のbuild.gradleに以下を追加します。
implementation 'com.android.support:recyclerview-v7:28.0.0-rc02'
##Realmを使えるように設定
project直下のbuild.gradleに以下を追加します。
classpath "io.realm:realm-gradle-plugin:5.4.2"
appディレクトリ直下のbuild.gradleに以下を追加します。
apply plugin: 'realm-android'
implementation 'io.realm:android-adapters:2.1.1'
proguardの設定については以下の参照をお願いします。
https://realm.io/jp/docs/java/0.80.3/#proguard
######以上で一度コンパイルをしてもらい、通れば問題ありません。
##Realmを初期化するためにApplicationクラスを継承してCustomApplicationクラスを作成
ApplicationクラスのonCreate()メソッド内に以下を追加します。
Realm.init(this)
val realmConfiguration = RealmConfiguration.Builder().build()
Realm.deleteRealm(realmConfiguration) // Delete Realm between app restarts.
Realm.setDefaultConfiguration(realmConfiguration)
Realm.deleteRealm(realmConfiguration);
この一行でデータを全て削除してしまうので、アプリの挙動に合わせて調整をお願いします。
##Realmで使用するためのモデルクラスを用意する
こちらはKotlinファイルを用意して以下の1行だけになります。
open class Person(@PrimaryKey var id: Int? = null, var name: String? = null, var age: Int? = null, var gender: String? = null): RealmObject()
##RecyclerViewを持ったActivityのレイアウトファイルを用意する
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
</android.support.constraint.ConstraintLayout>
</layout>
##RecyclerViewで使用するセルのレイアウトを用意する
LinearLayoutに対してidを設定しているのは背景色を設定して見やすくするためです。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/cell_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical">
<TextView
android:id="@+id/cell_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cell_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/cell_gender"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
##RecyclerViewに設定するadapterを用意する
Realmを簡単に使うため、RealmRecyclerViewAdapterを継承して使用しています。
class CustomRealmRecyclerViewAdapter(private val context: Context, private val collection: OrderedRealmCollection<Person>?, private val autoUpdate: Boolean)
: RealmRecyclerViewAdapter<Person, CustomRealmRecyclerViewAdapter.CustomViewHolder>(collection, autoUpdate) {
override fun getItemCount(): Int {
return collection?.size ?: 0
}
override fun onCreateViewHolder(parent: ViewGroup, position: Int): CustomViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.view_cell, parent, false)
return CustomViewHolder(DataBindingUtil.bind(view)!!)
}
override fun onBindViewHolder(viewHolder: CustomViewHolder, position: Int) {
val person = collection?.get(position)
viewHolder.binding.cellName.text = person?.name
viewHolder.binding.cellAge.text = person?.age.toString()
viewHolder.binding.cellGender.text = person?.gender
viewHolder.binding.cellLayout.setBackgroundColor(if (position % 2 == 0) Color.LTGRAY else Color.WHITE)
}
class CustomViewHolder(val binding: ViewCellBinding): RecyclerView.ViewHolder(binding.root)
}
##RecyclerViewにadapterを設定する
onCreate内でこれから必要なデータを作成する都合でonStart()メソッド内でadapterの設定を行っています。
アプリに合わせた修正を適宜お願いします。
override fun onStart() {
super.onStart()
val realmResults = mRealm.where(Person::class.java).findAll()
mBinding.recyclerView.adapter = CustomRealmRecyclerViewAdapter(applicationContext, realmResults, false)
}
##アダプターに流し込むデータを用意する
とりあえずのデータを100件用意しています。onCreate()メソッド内でデータの作成を行っていますが、実際に使う場合ではretrofit等でサーバーからデータを取得した後にデータの保存処理は行うと思われます。
mRealm = Realm.getDefaultInstance()
mRealm.executeTransaction{
val list = mutableListOf<Person>()
for (i in 0..99) {
list.add(Person(i, "ほげほげ:" + i.toString(), i, if (i % 2 == 0) "男" else "女"))
}
it.copyToRealmOrUpdate(list)
}
##Realmの後処理をする
override fun onDestroy() {
super.onDestroy()
mRealm.close()
}
##AndroidManifestにCustomApplication使うように指定する
<application
android:name=".application.CustomApplication" ←追加する
######以上で実行して問題なければ以下のように表示されると思います。