KotlinでRealm利用【RecycleView】

今回はRealmを用いたデータをRecycleviewで表示する方法です。

 

まずRecyclerViewが使えるようにライブラリを追加します。

build.gradleを開き以下のように書き加えます。

dependencies {
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

 

RecycleViewのレイアウトを追加します。

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

 

リストを表示する際の、セルのレイアウトを作成します。

(row.xmlファイル)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="56dp"
    android:layout_width="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:background="?android:attr/selectableItemBackground"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toEndOf="@+id/textview"
        android:layout_toRightOf="@+id/textview"
        android:background="?android:attr/selectableItemBackground"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textSize="16sp"
        android:textStyle="bold" />
</RelativeLayout>

それでは、MainActivityなどの表示したいところで

表示するための処理を書いていきます。

 

必要な内容は以下になります。

・Adapterクラスの作成(MyRecyclerViewAdapter.ktとします。)

・ViewHolderの作成。

・MainActivity内

→adapterのセット(必須)

→LayoutManagerの設定(必須)

 

 

・Adapterクラスの作成

internal class MyRecyclerViewAdapter(data: OrderedRealmCollection<Board>) :
        RealmRecyclerViewAdapter<Board, MyRecyclerViewAdapter.MyViewHolder>(data, true) {


    init {
        setHasStableIds(true)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.row, parent, false)
        return MyViewHolder(itemView)
    }

    // 実際にアイテムに受け取ったデータをセット
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val obj = getItem(position)
        val itemId = obj!!.id

        //ビューホルダーに値を入れる
        holder.id?.text = obj.id.toString()
        holder.name?.text = obj.name
    }

    override fun getItemId(index: Int): Long {
        return getItem(index)!!.id.toLong()
    }

    internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var id: TextView? = null
        var name: TextView? = null
        init {
            //ビューホルダーの情報がレイアウトのどれと対応するか
            id = view.findViewById(R.id.textview)
            name = view.findViewById(R.id.textview2)
        }
    }
}

では作成したMyRecyclerViewAdapterクラスのコードを順にみていきます。

まず引数のdataの型は

「 OrderedRealmCollection<Board> 」

となっています。

これはActivity側で一覧表示するために取得したRealmのBoardテーブルの

データコレクション(RealmResult)です。

 

このクラスは

RealmRecyclerViewAdapter<Board, MyRecyclerViewAdapter.MyViewHolder>(data, true)

RealmRecyclerViewAdapterを継承しています。

 

RecyclerViewではRealmResultをRecyclerViewで使用するために、

アダプタのベースを書いた、RealmRecyclerViewAdapterを継承して

オリジナルのアダプタを作成する必要があります。

 

 

(以下参考RealmRecyclerViewAdapter抽象クラス  gotoで見れます。)

public abstract class RealmRecyclerViewAdapter<T extends RealmModel, S extends RecyclerView.ViewHolder>
        extends RecyclerView.Adapter<S> {
 //以下略

 

 

ListViewからRecycleViewに変えて実装しようするとハマリがちかもしれません。

Realmはクエリ結果となるRealmResultをListViewで表示するためのアダプタとしてRealmBaseAdapterを用意していますが、これはListViewを使用する場合は問題ないですがRecyclerViewではこれを使用できないようになっています。
ちなみにこのクラスでは以下の三つの関数をoverrideして書かないといけないので、
・onCreateViewHolder
 (一つ分のViewHolderを作成する。ここでセルのレイアウト指定を行う)
・onBindViewHolder
   (作成したViewHolderにデータをセットする)
・getItemId
 (表示するアイテムの個数を返す必要がある。)
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.row, parent, false)
return MyViewHolder(itemView)
}

// 実際にアイテムに受け取ったデータをセット
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val obj = getItem(position)
val itemId = obj!!.id

//ビューホルダーに値を入れる
holder.id?.text = obj.id.toString()
holder.name?.text = obj.name
}

override fun getItemId(index: Int): Long {
return getItem(index)!!.id.toLong()
}
・ViewHolderの作成
このコードではわざわざ分ける必要もないと思ったので
ViewHolderを内部クラスとして実装していますが、
個別にクラスファイルを作っても大丈夫です。
 internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
 var id: TextView? = null
 var name: TextView? = null
 init {
 //ビューホルダーの情報がレイアウトのどれと対応するか
  id = view.findViewById(R.id.textview)
  name = view.findViewById(R.id.textview2)
 }
レイアウトのidに対応したデータをビューホルダーに登録しています。
この辺の部分に関しては
こちらが図を用いて詳しく記述されていますので見るのをお勧めします!
・MainActivity内のセット
my_recycler_viewはRecycleViewのid名です。
adapter = MyRecyclerViewAdapter(mRealm.where<Board>(Board::class.java!!).findAll())
my_recycler_view.layoutManager = LinearLayoutManager(this) //レイアウトのセット
my_recycler_view.adapter = adapter //adapterのセット
my_recycler_view.setHasFixedSize(true) //データの数が固定であれば、パフォーマンスを向上させる。
my_recycler_view.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
最初のadapterの代入部分では、
adapter = MyRecyclerViewAdapter(mRealm.where<Board>(Board::class.java!!).findAll())
RealmでBoardテーブルのデータを全て取得したもの(RealmResult)を引数にして、
MyRecyclerViewAdapterクラスのインスタンスを生成して代入しています。
それから、
LayoutManagerで表示の仕方をグリッドレイアウトやリニアーレイアウトから選んで、
adapterをセットすることで画面に表示されるようになります。。
(あらかじめデータを入れています。)
補足ですが、クラスの継承などで色々と下記のようなimportが必要に
なりますが、importされてなくてもエラーが出てる部分で、
Alt+Enterでimportが簡単にできるので省略しております。
import io.realm.OrderedRealmCollection
import io.realm.RealmRecyclerViewAdapter

あわせて読みたい

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です